当前位置: 首页 > 科技观察

这两个小技巧,让SQL语句不仅躲了坑,还提升了1000倍_0

时间:2023-03-21 00:29:38 科技观察

这两个技巧不仅避免了SQL语句的陷阱,还提高了1000倍。查询效率。1、允许字段的值为null,往往会导致灾难。首先,先准备一些数据,然后演示createtableanimal(idint,namechar(20),index(id))engine=innodb;index(id)为id字段创建一个索引,id和name都允许为null。然后插入4条数据,最后一条数据的id为.insertintoanimal(id,name)values(1,'cat');insertintoanimal(id,name)values(2,'dog');insertintoanimal(id,name)values(3,'pig');insertintoanimal(id,name)))values(null,'未命名的动物');此时表中的数据为此时我们查询表中有哪些动物的id!=1select*fromanimalwhereid!=1;结果如下:此时只找到两行数据,按道理应该是三行,但是没有匹配到id=null的那一行。您可能听说过null不等于任何其他值。从逻辑上讲,null!=1是正确的,但现实是残酷的,它只是不会匹配。所以,该字段的值是坚决不允许为null的,否则可能会出现意想不到的结果。反正这个坑我以前踩过,不知道你踩过没有?但是,如果有人将allow值设置为null怎么办?如果是这种情况,对于!=的搜索,您可以在后面添加一个oridisnull子句(注意,是null,而不是=null,因为id=null不会匹配值为null的行)。即select*fromanimalwhereid!=1oridisnull;结果如下:2.尽量用union代替or(1)。刚才我们已经为id字段创建了一个索引。如果我们进行等价操作,一般会使用索引操作。不信你看:explainselect*fromanimalwhereid=1;结果如下:从执行计划可以看出id上的等效搜索可以使用索引查询(估计在你的预料之内),其中type=ref:表示使用非唯一索引rows=1:预测扫描一行(2),id为null会不会使用索引?答案是肯定的,如图explainselect*fromanimalwhereidisnull;wheretype=ref:表示非唯一索引rows=1:预测扫描一行(3),那么问题来了,如果我们想找出id=1或id=null的动物,我们可以使用or语句连接,即select*fromanimalwhereid=1oridisnull;那么这个语句会使用索引吗?有没有索引看执行计划就知道了,如图explainselect*fromanimalwhereid=1oridisnull;其中:ref=ALL:表示全表扫描rows=4:预测扫描4行(而我们整个表只有4行记录)通过执行计划可以看出使用or很有可能不使用索引,会大大降低查询速度,所以一般不建议使用or子句来连接条件。那么如何解决呢?其实可以用union代替or,如下:select*fromanimalwhereid=1unionselect*fromanimalwhereidisnull。这时候索引会遍历两次,找到所有id=1且所有id=null的行,然后使用临时表存储最终结果,最后扫描临时表。