These two little tricks to make my SQL statement not only to hide the pit, also improved 1000 times

Original:  https://cloud.tencent.com/developer/article/1465618

The SQL query to explain with two little knowledge related to master this knowledge point, allowing you to avoid stepping pit and improve query efficiency.

1, allowing the value is null fields, often lead to disaster

First, prepare data point, behind a good demo

create table animal(
id int,
name char(20), index(id) )engine=innodb;

index (id) represents the id field to create the index, and the id and name are allowed to be null.

Then insert the four data, where id is the last data.

insert into animal(id, name) values(1, '猫'); insert into animal(id, name) values(2, '狗'); insert into animal(id, name) values(3, '猪'); insert into animal(id, name) values(null, '无名动物');

( Note: The code block may be pulled around )

At this time, data in the table is

Then we query the table id! = 1 What are the animals

select * from animal where id != 1;

The results are as follows:

At this point we found only two rows of data, is supposed to be three lines, but id = null this line is not actually match that , and we may have heard, null values are not equal to any other, it stands to reason null ! = 1 is tenable, but the reality is very cruel, it is not to be matched.

So, determined not to field value is null, otherwise do not meet the expected results may occur.

Anyway, I have stepped before the pit, do not know if you stepped on wood?

But what if someone has a null value allows how to do? If it is really so, for the! = Lookup, you can add an extra back or id is null clause (note that is null, is not = null, since id = null does not match the value is null lines). which is

select * from animal where id != 1 or id is null;

The results are as follows:

2, instead of or as a union

(1), we have just established a field to id this index, if we are to carry out the equivalent operation, it will generally take the index operation, do not believe you can see:

explain select * from animal where id = 1;

The results are as follows:

You can see through the implementation of programs, find the equivalent on the id index query can go (your estimate expected), which

type = ref: take the express non-unique index rows = 1: predictive scan line

(2), that id is null would take the index it? A will, as

explain select * from animal where id is null;

among them

type = ref: take the express non-unique index rows = 1: predictive scan line

(3), then the question is, that if we want to find id of animal id = null = 1 or, we might use to connect or statements that

select * from animal where id = 1 or id is null;

So this statement will take the index it?

There is no taking the index to see the implementation plan will know, as

explain select * from animal where id = 1 or id is null;

among them:

ref = ALL: represents a full table scan

rows = 4: 4 predicted scanning lines (and our entire table only 4 rows)

It can be seen through the implementation of programs, is likely to use or not taking the index, which will greatly reduce the rate of inquiries, it is generally not recommended or clause to the join condition.

So how to solve?

In fact, can union be substituted or, i.e., as follows:

select * from animal where id = 1 union select * from animal where id is null.

此时就会分别走两次索引,找出所有 id = 1 和 所有 id = null  的行,然后再用一个临时表来存放最终的结果,最后再扫描临时表。

3、总结

1、定义表的时候,尽量不允许字段值为 null,可以用 default 设置默认值。

2、尽量用 union 来代替 or,避免查询没有走索引。

3、注意,用 id = null 的等值查询,也是不会匹配到值为 null 的行的,而是应该用 id is null。

也欢迎大家说一说自己踩过的坑

Guess you like

Origin www.cnblogs.com/sunsky303/p/11344133.html