婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > SQL優(yōu)化教程之in與range查詢

SQL優(yōu)化教程之in與range查詢

熱門標(biāo)簽:400電話鄭州申請 北京人工外呼系統(tǒng)價錢 常州電銷外呼系統(tǒng)一般多少錢 沃克斯電梯外呼線路圖 房產(chǎn)智能外呼系統(tǒng)品牌 福州呼叫中心外呼系統(tǒng)哪家好 天智外呼系統(tǒng) 云南語音外呼系統(tǒng)平臺 地圖標(biāo)注被騙三百怎么辦

前言

《高性能MySQL》里面提及用in這種方式可以有效的替代一定的range查詢,提升查詢效率, 因為在一條索引里面,range字段后面的部分是不生效的(ps.需要考慮 ICP) 。MySQL優(yōu)化器將in這種方式轉(zhuǎn)化成  n*m 種組合進行查詢,最終將返回值合并,有點類似union但是更高效。

MySQL在 IN() 組合條件過多的時候會發(fā)生很多問題。查詢優(yōu)化可能需要花很多時間,并消耗大量內(nèi)存。新版本MySQL在組合數(shù)超過一定的數(shù)量就不進行計劃評估了,這可能導(dǎo)致MySQL不能很好的利用索引。

這里的 一定數(shù) 在MySQL5.6.5以及以后的版本中是由eq_range_index_dive_limit這個參數(shù)控制 。默認(rèn)設(shè)置是10,一直到5.7以后的版本默認(rèn)修改為200,當(dāng)然可以手動設(shè)置的。5.6手冊說明如下:

The eq_range_index_dive_limit system variable enables you to configure the number of values at which the optimizer switches from one row estimation strategy to the other. To disable use of statistics and always use index dives, set eq_range_index_dive_limit to 0. To permit use of index dives for comparisons of up to N equality ranges, set eq_range_index_dive_limit to N + 1. eq_range_index_dive_limit is available as of MySQL 5.6.5. Before 5.6.5, the optimizer uses index dives, which is equivalent to eq_range_index_dive_limit=0.

換言之,

eq_range_index_dive_limit = 0 只能使用index dive

0 eq_range_index_dive_limit = N 使用index statistics

eq_range_index_dive_limit > N 只能使用index dive

在MySQL5.7版本中將默認(rèn)值從10修改成200目的是為了盡可能的保證范圍等值運算(IN())執(zhí)行計劃盡量精準(zhǔn),因為IN()list的數(shù)量很多時候都是超過10的。

在MySQL的官方手冊上有這么一句話:

the optimizer can estimate the row count for each range using dives into the index or index statistics.

大意:

優(yōu)化器預(yù)估每個范圍段--如"a IN (10, 20, 30)" 視為等值比較, 括3個范圍段實則簡化為3個單值,分別是10,20,30--中包括的元組數(shù),用范圍段來表示是因為 MySQL 的"range"掃描方式多數(shù)做的是范圍掃描,此處單值可視為范圍段的特例;

估計方法有2種:

  1. dive到index中即利用索引完成元組數(shù)的估算,簡稱index dive;
  2. index statistics:使用索引的統(tǒng)計數(shù)值,進行估算;

對比這兩種方式

  1. index dive: 速度慢,但能得到精確的值(MySQL的實現(xiàn)是數(shù)索引對應(yīng)的索引項個數(shù),所以精確)
  2. index statistics: 速度快,但得到的值未必精確

簡單說,**選項 eq_range_index_dive_limit 的值設(shè)定了 IN列表中的條件個數(shù)上線,超過設(shè)定值時,會將執(zhí)行計劃從 index dive 變成 index statistics **。

為什么要區(qū)分這2種方式呢?

  1. 查詢優(yōu)化器會使用代價估算模型計算每個計劃的代價,選擇其中代價最小的
  2. 單表掃描時,需要計算代價;所以單表的索引掃描也需要計算代價
  3. 單表的計算公式通常是:  代價 = 元組數(shù) * IO平均值
  4. 所以不管是哪種掃描方式,都需要計算元組數(shù)
  5. 當(dāng)遇到“a IN (10, 20, 30)”這樣的表達式的時候,發(fā)現(xiàn)a列存在索引,則需要看這個索引可以掃描到的元組數(shù)由多少而計算其索引掃描代價,所以就用到了本文提到的“index dive”、“index statistics”這2種方式。

討論主題

  1. range查詢與索引使用
  2. eq_range_index_dive_limit的說明

range查詢與索引使用

SQL如下:

SELECT * FROM pre_forum_post WHERE tid=7932552 AND invisible IN('0','-2') ORDER BY dateline DESC LIMIT 10;

索引如下:

PRIMARY(tid,position),
pid(pid),
fid(tid),
displayorder(tid,invisible,dateline)
first(tid,first)
new_auth(authorid,invisible,tid)
idx_dt(dateline)
mul_test(tid,invisible,dateline,pid)

看下執(zhí)行計劃:

root@localhost 16:08:27 [ultrax]> explain SELECT * FROM pre_forum_post WHERE tid=7932552 AND `invisible` IN('0','-2') 
 -> ORDER BY dateline DESC LIMIT 10;
+----+-------------+----------------+-------+-------------------------------------------+--------------+---------+------+------+---------------------------------------+
| id | select_type | table | type | possible_keys  | key | key_len | ref | rows | Extra   |
+----+-------------+----------------+-------+-------------------------------------------+--------------+---------+------+------+---------------------------------------+
| 1 | SIMPLE | pre_forum_post | range | PRIMARY,displayorder,first,mul_test,idx_1 | displayorder | 4 | NULL | 54 | Using index condition; Using filesort | 
+----+-------------+----------------+-------+-------------------------------------------+--------------+---------+------+------+---------------------------------------+
1 row in set (0.00 sec)

MySQL優(yōu)化器認(rèn)為這是一個range查詢,那么(tid,invisible,dateline)這條索引中,dateline字段肯定用不上了,也就是說這個SQL最后的排序肯定會生成一個臨時結(jié)果集,然后再結(jié)果集里面完成排序,而不是直接在索引中直接完成排序動作,于是我們嘗試增加了一條索引。

root@localhost 16:09:06 [ultrax]> alter table pre_forum_post add index idx_1 (tid,dateline); 
Query OK, 20374596 rows affected, 0 warning (600.23 sec)
Records: 0 Duplicates: 0 Warnings: 0
root@localhost 16:20:22 [ultrax]> explain SELECT * FROM pre_forum_post force index (idx_1) WHERE tid=7932552 AND `invisible` IN('0','-2') ORDER BY dateline DESC LIMIT 10;
+----+-------------+----------------+------+---------------+-------+---------+-------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------+------+---------------+-------+---------+-------+--------+-------------+
| 1 | SIMPLE | pre_forum_post | ref | idx_1 | idx_1 | 3 | const | 120646 | Using where | 
+----+-------------+----------------+------+---------------+-------+---------+-------+--------+-------------+
1 row in set (0.00 sec)
root@localhost 16:22:06 [ultrax]> SELECT sql_no_cache * FROM pre_forum_post WHERE tid=7932552 AND `invisible` IN('0','-2') ORDER BY dateline DESC LIMIT 10;
...
10 rows in set (0.40 sec)
root@localhost 16:23:55 [ultrax]> SELECT sql_no_cache * FROM pre_forum_post force index (idx_1) WHERE tid=7932552 AND `invisible` IN('0','-2') ORDER BY dateline DESC LIMIT 10;
...
10 rows in set (0.00 sec)

實驗證明效果是極好的,其實不難理解,上面我們就說了in()在MySQL優(yōu)化器里面是以多種組合方式來檢索數(shù)據(jù)的,如果加了一個排序或者分組那勢必只能在臨時結(jié)果集上操作,也就是說索引里面即使包含了排序或者分組的字段依然是沒用的。唯一不滿的是MySQL優(yōu)化器的選擇依然不夠靠譜。

總結(jié)下:在MySQL查詢里面使用in(),除了要注意in()list的數(shù)量以及eq_range_index_dive_limit的值以外(具體見下),還要注意如果SQL包含排序/分組/去重等等就需要注意索引的使用。

eq_range_index_dive_limit的說明

還是上面的案例,為什么idx_1無法直接使用?需要使用hint強制只用這個索引呢?這里我們首先看下eq_range_index_dive_limit的值。

root@localhost 22:38:05 [ultrax]> show variables like 'eq_range_index_dive_limit';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| eq_range_index_dive_limit | 2 | 
+---------------------------+-------+
1 row in set (0.00 sec)

根據(jù)我們上面說的這種情況0 eq_range_index_dive_limit = N使用index statistics,那么接下來我們用OPTIMIZER_TRACE來一看究竟。

{
 "index": "displayorder",
 "ranges": [
 "7932552 = tid = 7932552 AND -2 = invisible = -2",
 "7932552 = tid = 7932552 AND 0 = invisible = 0"
 ],
 "index_dives_for_eq_ranges": false,
 "rowid_ordered": false,
 "using_mrr": false,
 "index_only": false,
 "rows": 54,
 "cost": 66.81,
 "chosen": true
}
// index dive為false,最終chosen是true
...
{
 "index": "idx_1",
 "ranges": [
 "7932552 = tid = 7932552"
 ],
 "index_dives_for_eq_ranges": true,
 "rowid_ordered": false,
 "using_mrr": false,
 "index_only": false,
 "rows": 120646,
 "cost": 144776,
 "chosen": false,
 "cause": "cost"
}

我們可以看到displayorder索引的cost是66.81,而idx_1的cost是120646,而最終MySQL優(yōu)化器選擇了displayorder這條索引。那么如果我們把eq_range_index_dive_limit設(shè)置>N是不是應(yīng)該就會使用index dive計算方式,得到更準(zhǔn)確的執(zhí)行計劃呢?

root@localhost 22:52:52 [ultrax]> set eq_range_index_dive_limit = 3;
Query OK, 0 rows affected (0.00 sec)
root@localhost 22:55:38 [ultrax]> explain SELECT * FROM pre_forum_post WHERE tid=7932552 AND `invisible` IN('0','-2') ORDER BY dateline DESC LIMIT 10;
+----+-------------+----------------+------+-------------------------------------------+-------+---------+-------+--------+-------------+
| id | select_type | table | type | possible_keys  | key | key_len | ref | rows | Extra |
+----+-------------+----------------+------+-------------------------------------------+-------+---------+-------+--------+-------------+
| 1 | SIMPLE | pre_forum_post | ref | PRIMARY,displayorder,first,mul_test,idx_1 | idx_1 | 3 | const | 120646 | Using where | 
+----+-------------+----------------+------+-------------------------------------------+-------+---------+-------+--------+-------------+
1 row in set (0.00 sec)

optimize_trace結(jié)果如下

{
 "index": "displayorder",
 "ranges": [
 "7932552 = tid = 7932552 AND -2 = invisible = -2",
 "7932552 = tid = 7932552 AND 0 = invisible = 0"
 ],
 "index_dives_for_eq_ranges": true,
 "rowid_ordered": false,
 "using_mrr": false,
 "index_only": false,
 "rows": 188193,
 "cost": 225834,
 "chosen": true
}
...
{
 "index": "idx_1",
 "ranges": [
 "7932552 = tid = 7932552"
 ],
 "index_dives_for_eq_ranges": true,
 "rowid_ordered": false,
 "using_mrr": false,
 "index_only": false,
 "rows": 120646,
 "cost": 144776,
 "chosen": true
}
...
 "cost_for_plan": 144775,
 "rows_for_plan": 120646,
 "chosen": true

在備選索引選擇中兩條索引都被選擇,在最后的邏輯優(yōu)化中選在了代價最小的索引也就是idx_1 以上就是在等值范圍查詢中eq_range_index_dive_limit的值怎么影響MySQL優(yōu)化器計算開銷,從而影響索引的選擇。另外我們可以通過profiling來看看優(yōu)化器的統(tǒng)計耗時:

index dive

+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000048 | 
| checking permissions | 0.000004 | 
| Opening tables | 0.000015 | 
| init  | 0.000044 | 
| System lock | 0.000009 | 
| optimizing | 0.000014 | 
| statistics | 0.032089 | 
| preparing | 0.000022 | 
| Sorting result | 0.000003 | 
| executing | 0.000003 | 
| Sending data | 0.000101 | 
| end  | 0.000004 | 
| query end | 0.000002 | 
| closing tables | 0.000009 | 
| freeing items | 0.000013 | 
| cleaning up | 0.000012 | 
+----------------------+----------+

index statistics

+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000045 | 
| checking permissions | 0.000003 | 
| Opening tables | 0.000014 | 
| init  | 0.000040 | 
| System lock | 0.000008 | 
| optimizing | 0.000014 | 
| statistics | 0.000086 | 
| preparing | 0.000016 | 
| Sorting result | 0.000002 | 
| executing | 0.000002 | 
| Sending data | 0.000016 | 
| Creating sort index | 0.412123 | 
| end  | 0.000012 | 
| query end | 0.000004 | 
| closing tables | 0.000013 | 
| freeing items | 0.000023 | 
| cleaning up | 0.000015 | 
+----------------------+----------+

可以看到當(dāng)eq_range_index_dive_limit加大使用index dive時,優(yōu)化器統(tǒng)計耗時明顯比ndex statistics方式來的長,但最終它使用了作出了更合理的執(zhí)行計劃。統(tǒng)計耗時0.032089s vs .000086s,但是SQL執(zhí)行耗時卻是約0.03s vs 0.41s。

附:

如何使用optimize_trace

set optimizer_trace='enabled=on';

select * from information_schema.optimizer_trace\G

注:optimizer_trace建議只在session模式下開啟調(diào)試即可

如何使用profile

set profiling=ON;
執(zhí)行sql;
show profiles;
show profile for query 2;
show profile block io,cpu for query 2;

另外還可以看到memory,swaps,context switches,source 等信息

參考資料

[1]MySQL SQL優(yōu)化系列之 in與range 查詢

https://www.jb51.net/article/201251.htm

[2]MySQL物理查詢優(yōu)化技術(shù)---index dive辨析

http://blog.163.com/li_hx/blog/static/18399141320147521735442/

到此這篇關(guān)于SQL優(yōu)化教程之in與range查詢的文章就介紹到這了,更多相關(guān)SQL優(yōu)化之in與range查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • 分析MySQL中優(yōu)化distinct的技巧
  • mysql in語句子查詢效率慢的優(yōu)化技巧示例
  • MySQL查詢優(yōu)化:連接查詢排序limit(join、order by、limit語句)介紹
  • MySQL優(yōu)化之使用連接(join)代替子查詢
  • SQL語句優(yōu)化之JOIN和LEFT JOIN 和 RIGHT JOIN語句的優(yōu)化
  • SQL優(yōu)化之針對count、表的連接順序、條件順序、in及exist的優(yōu)化
  • MySQL中對于not in和minus使用的優(yōu)化
  • 關(guān)于mysql中innodb的count優(yōu)化問題分享
  • MySQL中insert語句的使用與優(yōu)化教程

標(biāo)簽:徐州 沈陽 珠海 鹽城 移動 拉薩 黔東 沈陽

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《SQL優(yōu)化教程之in與range查詢》,本文關(guān)鍵詞  SQL,優(yōu)化,教程,之,與,range,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《SQL優(yōu)化教程之in與range查詢》相關(guān)的同類信息!
  • 本頁收集關(guān)于SQL優(yōu)化教程之in與range查詢的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    欧美日韩小视频| 久久精品国产精品青草| 欧美中文字幕一二三区视频| 欧美成人福利视频| 99国产精品久久久久| 另类小说一区二区三区| 一区二区三区四区五区视频在线观看 | 国产成人丝袜美腿| 首页国产丝袜综合| 午夜欧美视频在线观看 | 日韩成人精品在线| 亚洲同性同志一二三专区| 91日韩在线专区| 91视频xxxx| 日韩亚洲欧美成人一区| 91精品国产综合久久精品图片| 国产一区二区免费视频| 国产盗摄精品一区二区三区在线| 蜜桃视频一区二区三区在线观看| 美腿丝袜亚洲三区| 自拍偷拍国产亚洲| 亚洲一区在线观看免费观看电影高清| 国产精品九色蝌蚪自拍| 亚洲夂夂婷婷色拍ww47 | 亚洲欧美一区二区在线观看| 中文字幕乱码亚洲精品一区 | 日韩精品三区四区| 亚洲一区日韩精品中文字幕| 国产精品国产三级国产aⅴ原创| 精品第一国产综合精品aⅴ| 国产精品国产精品国产专区不蜜| 亚洲男同性恋视频| 青青草一区二区三区| 成人福利电影精品一区二区在线观看| 成人av一区二区三区| 26uuu亚洲综合色欧美| 中国色在线观看另类| 色哟哟亚洲精品| 欧美精品久久一区二区三区| 亚洲同性gay激情无套| 国产成人免费高清| 7777精品伊人久久久大香线蕉的| 国产精品国产三级国产普通话蜜臀| 日韩一区二区电影网| 图片区日韩欧美亚洲| 欧亚洲嫩模精品一区三区| 在线观看日韩一区| 欧美一区二区在线免费播放| 日韩理论片在线| 国产精品888| 色嗨嗨av一区二区三区| 欧美性生活一区| 国产日韩影视精品| eeuss国产一区二区三区| 欧美激情一区二区三区全黄| 国产大陆a不卡| 亚洲欧美电影院| 成人99免费视频| 亚洲另类中文字| 欧美一区二区在线免费播放| 青青国产91久久久久久| 91精品国产综合久久久蜜臀粉嫩| 日本在线播放一区二区三区| 日韩美一区二区三区| 成人国产免费视频| 日日噜噜夜夜狠狠视频欧美人| 欧美一级夜夜爽| 欧美aⅴ一区二区三区视频| 日韩欧美国产午夜精品| 欧美成人一区二区三区片免费 | 亚洲国产精品一区二区www| 国产91在线|亚洲| 日本不卡一区二区三区| 精品日韩99亚洲| 色综合 综合色| 国产成人免费在线视频| 丝袜a∨在线一区二区三区不卡| 精品久久久久香蕉网| 欧美私人免费视频| 久久激情五月婷婷| 欧美一级一区二区| 成人高清视频在线观看| 九九九久久久精品| 午夜欧美大尺度福利影院在线看| 国产精品久久久久久久第一福利 | 美女视频黄频大全不卡视频在线播放| 日韩精品一区二区三区老鸭窝| 三级亚洲高清视频| 亚洲天堂久久久久久久| 欧美性受xxxx| 国产成人av一区二区三区在线| 六月婷婷色综合| 美日韩一区二区三区| 蜜臀av一区二区在线观看| 国产视频亚洲色图| 色婷婷av一区二区三区大白胸| 久久精品国产99国产精品| 免费看日韩精品| 国内外成人在线| 国产精品一二三四五| 日韩欧美在线影院| 久久色在线观看| 国产亚洲精品精华液| 自拍偷拍亚洲欧美日韩| 午夜精品国产更新| 国内精品久久久久影院薰衣草| 亚洲啪啪综合av一区二区三区| 亚洲男人的天堂在线aⅴ视频| 久久色在线视频| 亚洲一区精品在线| 一区二区在线观看不卡| 免费在线观看日韩欧美| 日韩高清不卡在线| 国产精品一二三四| 欧美人妖巨大在线| 91精品91久久久中77777| 日韩免费高清av| 亚洲精品乱码久久久久久久久| 国产精品国产自产拍高清av| 亚洲一区在线看| 色网综合在线观看| 亚洲女与黑人做爰| 99国产精品久久久| 中文字幕永久在线不卡| 国产乱理伦片在线观看夜一区| 91精品国产日韩91久久久久久| 亚洲手机成人高清视频| 欧美中文字幕一区二区三区| 日韩高清不卡一区| 国产欧美日韩精品a在线观看| 99久久免费视频.com| 午夜精品一区二区三区三上悠亚| 日韩欧美成人一区| 成人午夜精品在线| 免费欧美在线视频| 亚洲日韩欧美一区二区在线| 欧美日韩国产成人在线91| 毛片av一区二区| 亚洲午夜私人影院| 国产亚洲精品7777| 91精品国产手机| 精品视频免费在线| 国产一区二区影院| 午夜精品一区在线观看| 国产精品成人一区二区艾草| 欧美一激情一区二区三区| 一本久道久久综合中文字幕| 狠狠久久亚洲欧美| 理论片日本一区| 日韩av电影免费观看高清完整版在线观看| 国产午夜精品一区二区| 337p亚洲精品色噜噜| 欧美天天综合网| 欧美日韩一区国产| 欧美一级专区免费大片| 欧美日韩一卡二卡| 欧美日韩视频一区二区| 色婷婷激情综合| 91精品91久久久中77777| 日本韩国欧美国产| 在线播放中文一区| 日韩欧美精品三级| 久久久久久日产精品| 国产欧美日韩在线看| 亚洲欧美日韩精品久久久久| 国产精品国产自产拍高清av | 日韩毛片精品高清免费| 国产精品高潮呻吟| 亚洲自拍偷拍麻豆| 日韩激情中文字幕| 国产伦精品一区二区三区免费迷| 成人爽a毛片一区二区免费| 国产麻豆成人精品| 欧美日韩一区三区| 欧美成人一级视频| 国产精品久久久久久久久免费樱桃 | 91精品国产一区二区三区| 日韩精品一区二区三区在线观看 | 99re这里都是精品| 欧美一区二区三区四区久久 | 国产麻豆精品视频| 欧美性生交片4| 国产精品久久久久毛片软件| 婷婷丁香激情综合| 国产一区视频网站| 欧美日本在线观看| 国产精品毛片a∨一区二区三区| 亚洲国产日产av| 91成人网在线| 亚洲国产成人私人影院tom| 日韩av不卡在线观看| 色婷婷久久99综合精品jk白丝| 日韩欧美中文一区| 日韩va欧美va亚洲va久久| 99久久久久久| 久久精品在这里| 国产999精品久久| 中文字幕亚洲不卡| 91美女视频网站| 国产精品高潮呻吟久久|