人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動(dòng)態(tài)

導(dǎo)致MySQL做全表掃描的幾種情況

發(fā)布日期:2022-02-14 19:47 | 文章來(lái)源:gibhub

這兩天看到了兩種可能會(huì)導(dǎo)致全表掃描的sql,這里給大家看一下,希望可以避免踩坑:

情況1:

強(qiáng)制類(lèi)型轉(zhuǎn)換的情況下,不會(huì)使用索引,會(huì)走全表掃描。

舉例如下:

首先我們創(chuàng)建一個(gè)表

CREATETABLE`test`(
`id`int(11)NOTNULLAUTO_INCREMENT,
`age`int(11)DEFAULTNULL,
`score`varchar(20)NOTNULLDEFAULT'',
PRIMARYKEY(`id`),
KEY`idx_score`(`score`)
)ENGINE=InnoDBAUTO_INCREMENT=12DEFAULTCHARSET=utf8

我們可以看到,這個(gè)表有三個(gè)字段,其中兩個(gè)int類(lèi)型,一個(gè)varchar類(lèi)型。varchar類(lèi)型的字段score是一個(gè)索引,而id是主鍵。

然后我們給這個(gè)表里面插入一些數(shù)據(jù),插入數(shù)據(jù)之后的表如下:

mysql:yeyztest 21:43:12>>select*fromtest;
+----+------+-------+
|id|age|score|
+----+------+-------+
|1|1|5|
|2|2|10|
|5|5|25|
|8|8|40|
|9|2|45|
|10|5|50|
|11|8|55|
+----+------+-------+
7rowsinset(0.00sec)

這個(gè)時(shí)候,我們使用explain語(yǔ)句來(lái)查看兩條sql的執(zhí)行情況,分別是:

explain select * from test where score ='10';
explain select * from test where score =10;

結(jié)果如下:

mysql:yeyztest21:42:29>>explainselect*fromtestwherescore='10';
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
|id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra|
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
|1|SIMPLE|test|NULL|ref|idx_score|idx_score|62|const|1|100.00|NULL|
+----+-------------+-------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
1rowinset,1warning(0.00sec)
mysql:yeyztest21:43:06>>explainselect*fromtestwherescore=10;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra|
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|1|SIMPLE|test|NULL|ALL|idx_score|NULL|NULL|NULL|7|14.29|Usingwhere|
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1rowinset,3warnings(0.00sec)

可以看到,如果我們使用的是varchar類(lèi)型的值,那么結(jié)果中掃描的行數(shù)rows就是1,而當(dāng)我們使用的是整數(shù)值10的時(shí)候,掃描行數(shù)變?yōu)榱?,證明,如果出現(xiàn)了強(qiáng)制類(lèi)型轉(zhuǎn)換,則會(huì)導(dǎo)致索引失效。

情況2:

反向查詢(xún)不能使用索引,會(huì)導(dǎo)致全表掃描。

創(chuàng)建一個(gè)表test1,它的主鍵是score,然后插入6條數(shù)據(jù):

CREATETABLE`test1`(
`score`varchar(20) not null default '' ,
PRIMARYKEY(`score`)
)ENGINE=InnoDBDEFAULTCHARSET=utf8
mysql:yeyztest22:09:37>>select*fromtest1;
+-------+
|score|
+-------+
|111|
|222|
|333|
|444|
|555|
|666|
+-------+
6rowsinset(0.00sec)

當(dāng)我們使用反向查找的時(shí)候,不會(huì)使用到索引,來(lái)看下面兩條sql:

explain select * from test1 where score='111';
explain select * from test1 where score!='111';
mysql:yeyztest22:13:01>>explainselect*fromtest1wherescore='111';
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
|id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra|
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
|1|SIMPLE|test1|NULL|const|PRIMARY|PRIMARY|62|const|1|100.00|Usingindex|
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+
1rowinset,1warning(0.00sec)
mysql:yeyztest22:13:08>>explainselect*fromtest1wherescore!='111';
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra|
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|1|SIMPLE|test1|NULL|index|PRIMARY|PRIMARY|62|NULL|6|100.00|Usingwhere;Usingindex|
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1rowinset,1warning(0.00sec)

可以看到,使用!=作為條件的時(shí)候,掃描的行數(shù)是表的總記錄行數(shù)。因此如果想要使用索引,我們就不能使用反向匹配規(guī)則。

情況3:

某些or值條件可能導(dǎo)致全表掃描。

首先我們創(chuàng)建一個(gè)表,并插入幾條數(shù)據(jù):

CREATETABLE`test4`(
`id`int(11)DEFAULTNULL,
`name`varchar(20)DEFAULTNULL,
KEY`idx_id`(`id`)
)ENGINE=InnoDBDEFAULTCHARSET=utf8
1rowinset(0.00sec)
mysql--dba_admin@127.0.0.1:yeyztest22:23:44>>select*fromtest4;
+------+------+
|id|name|
+------+------+
|1|aaa|
|2|bbb|
|3|ccc|
|4|yeyz|
|NULL|yeyz|
+------+------+
5rowsinset(0.00sec)

其中表test4包含兩個(gè)字段,id字段是一個(gè)索引,而name字段是varchar類(lèi)型,我們來(lái)看下面三個(gè)語(yǔ)句的掃描行數(shù):

explain select * from test4 where id=1;
explain select * from test4 where id is null;
explain select * from test4 where id=1 or id is null;
mysql:yeyztest22:24:12>>explainselect*fromtest4whereidisnull;
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-----------------------+
|id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra|
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-----------------------+
|1|SIMPLE|test4|NULL|ref|idx_id|idx_id|5|const|1|100.00|Usingindexcondition|
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-----------------------+
1rowinset,1warning(0.00sec)
mysql:yeyztest22:24:17>>explainselect*fromtest4whereid=1;
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
|id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra|
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
|1|SIMPLE|test4|NULL|ref|idx_id|idx_id|5|const|1|100.00|NULL|
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------+
1rowinset,1warning(0.00sec)
mysql:yeyztest22:24:28>>explainselect*fromtest4whereid=1oridisnull;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra|
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|1|SIMPLE|test4|NULL|ALL|idx_id|NULL|NULL|NULL|5|40.00|Usingwhere|
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1rowinset,1warning(0.00sec)

可以看到單獨(dú)使用id=1和id is null,都只會(huì)掃描一行記錄,而使用or將二者連接起來(lái)就會(huì)導(dǎo)致掃描全表而不使用索引。

簡(jiǎn)單總結(jié)一下:

1.強(qiáng)制類(lèi)型轉(zhuǎn)換的情況下,不會(huì)使用索引,會(huì)走全表掃描

2.反向查詢(xún)不能使用索引,會(huì)導(dǎo)致全表掃描。

3.某些or值條件可能導(dǎo)致全表掃描。

以上就是導(dǎo)致MySQL做全表掃描的幾種情況的詳細(xì)內(nèi)容,更多關(guān)于MySQL 全表掃描的資料請(qǐng)關(guān)注本站其它相關(guān)文章!

美國(guó)服務(wù)器租用

版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開(kāi)通

自選配置、實(shí)時(shí)開(kāi)通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專(zhuān)屬顧問(wèn)服務(wù)

1對(duì)1客戶咨詢(xún)顧問(wèn)

在線
客服

在線客服:7*24小時(shí)在線

客服
熱線

400-630-3752
7*24小時(shí)客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部