MySQL:2020 端午節(jié)隨筆(索引下探和唯一索引特殊執(zhí)行計劃)

一法瑟、索引數(shù)據(jù)下探

http://blog.itpub.net/7728585/viewspace-2660796/

/*
Get the number of rows in the range. This is done by calling
records_in_range() unless:

    1) The range is an equality range and the index is unique.
       There cannot be more than one matching row, so 1 is
       assumed. Note that it is possible that the correct number
       is actually 0, so the row estimate may be too high in this
       case. Also note: ranges of the form "x IS NULL" may have more
       than 1 mathing row so records_in_range() is called for these.
    2) a) The range is an equality range but the index is either 
          not unique or all of the keyparts are not used. 
       b) The user has requested that index statistics should be used
          for equality ranges to avoid the incurred overhead of 
          index dives in records_in_range().
       c) Index statistics is available.
       Ranges of the form "x IS NULL" will not use index statistics 
       because the number of rows with this value are likely to be 
       very different than the values in the index statistics.
*/

handler::multi_range_read_info_const

  • 等值條件冀膝,根據(jù)參數(shù) eq_range_index_dive_limit 來判斷是否進行下探 0 始終 1 始終不 >1 判斷 or 的個數(shù)
  • 范圍 始終下探

疑問:下探的采樣范圍和原理

下探棧

(gdb) bt
#0  handler::multi_range_read_info_const (this=0x7fff0576eb00, keyno=2, seq=0x7fffe8d3ddb0, seq_init_param=0x7fffe8d3ddf0, n_ranges_arg=0, bufsz=0x7fffe8d3dd00, flags=0x7fffe8d3dd04, cost=0x7fffe8d3e1e0)
    at /cdh/mysqldebug/percona-server-5.7.29-32/sql/handler.cc:6651
#1  0x0000000000ec4364 in DsMrr_impl::dsmrr_info_const (this=0x7fff0576ef70, keyno=2, seq=0x7fffe8d3ddb0, seq_init_param=0x7fffe8d3ddf0, n_ranges=0, bufsz=0x7fffe8d3e2e0, flags=0x7fffe8d3e2e4, 
    cost=0x7fffe8d3e1e0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/handler.cc:7391
#2  0x000000000198cbc1 in ha_innobase::multi_range_read_info_const (this=0x7fff0576eb00, keyno=2, seq=0x7fffe8d3ddb0, seq_init_param=0x7fffe8d3ddf0, n_ranges=0, bufsz=0x7fffe8d3e2e0, flags=0x7fffe8d3e2e4, 
    cost=0x7fffe8d3e1e0) at /cdh/mysqldebug/percona-server-5.7.29-32/storage/innobase/handler/ha_innodb.cc:23185
#3  0x0000000001733252 in check_quick_select (param=0x7fffe8d3e550, idx=0, index_only=false, tree=0x7fff040c0ed0, update_tbl_stats=true, mrr_flags=0x7fffe8d3e2e4, bufsize=0x7fffe8d3e2e0, cost=0x7fffe8d3e1e0)
    at /cdh/mysqldebug/percona-server-5.7.29-32/sql/opt_range.cc:10099
#4  0x000000000172a110 in get_key_scans_params (param=0x7fffe8d3e550, tree=0x7fff040c0e08, index_read_must_be_used=false, update_tbl_stats=true, cost_est=0x7fffe8d3e430)
    at /cdh/mysqldebug/percona-server-5.7.29-32/sql/opt_range.cc:5854
#5  0x0000000001723c21 in test_quick_select (thd=0x7fff04000bf0, keys_to_use=..., prev_tables=0, limit=18446744073709551615, force_quick_range=false, interesting_order=st_order::ORDER_NOT_RELEVANT, 
    tab=0x7fff057734a8, cond=0x7fff04007538, needed_reg=0x7fff057734e8, quick=0x7fffe8d40a38, ignore_table_scan=false) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/opt_range.cc:3108
#6  0x00000000014b2aa9 in get_quick_record_count (thd=0x7fff04000bf0, tab=0x7fff057734a8, limit=18446744073709551615) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_optimizer.cc:6013
#7  0x00000000014b2172 in JOIN::estimate_rowcount (this=0x7fff057730d0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_optimizer.cc:5760
#8  0x00000000014b05eb in JOIN::make_join_plan (this=0x7fff057730d0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_optimizer.cc:5117
#9  0x00000000014a4d06 in JOIN::optimize (this=0x7fff057730d0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_optimizer.cc:394
#10 0x000000000151f92b in st_select_lex::optimize (this=0x7fff04005d50, thd=0x7fff04000bf0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_select.cc:1018
#11 0x000000000151e053 in handle_query (thd=0x7fff04000bf0, lex=0x7fff040032a0, result=0x7fff04007780, added_options=0, removed_options=0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_select.cc:172
#12 0x00000000014d1d93 in execute_sqlcom_select (thd=0x7fff04000bf0, all_tables=0x7fff04006e58) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_parse.cc:5475
#13 0x00000000014cb119 in mysql_execute_command (thd=0x7fff04000bf0, first_level=true) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_parse.cc:3016
#14 0x00000000014d2e1b in mysql_parse (thd=0x7fff04000bf0, parser_state=0x7fffe8d424a0, update_userstat=false) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_parse.cc:5927
#15 0x00000000014c7a55 in dispatch_command (thd=0x7fff04000bf0, com_data=0x7fffe8d42c90, command=COM_QUERY) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_parse.cc:1539
#16 0x00000000014c688a in do_command (thd=0x7fff04000bf0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_parse.cc:1060
#17 0x00000000015fab28 in handle_connection (arg=0x3443230) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/conn_handler/connection_handler_per_thread.cc:325
#18 0x00000000018cad34 in pfs_spawn_thread (arg=0x3dd00c0) at /cdh/mysqldebug/percona-server-5.7.29-32/storage/perfschema/pfs.cc:2198
#19 0x00007ffff7bc6e65 in start_thread () from /lib64/libpthread.so.0
#20 0x00007ffff5fa088d in clone () from /lib64/libc.so.6


#0  btr_cur_search_to_nth_level (index=0x7fff0494e320, level=0, tuple=0x7fff04a619b0, mode=PAGE_CUR_GE, latch_mode=1025, cursor=0x7fffe8d39310, has_search_latch=0, 
    file=0x2311530 "/cdh/mysqldebug/percona-server-5.7.29-32/storage/innobase/btr/btr0cur.cc", line=5913, mtr=0x7fffe8d393b0) at /cdh/mysqldebug/percona-server-5.7.29-32/storage/innobase/btr/btr0cur.cc:798
#1  0x0000000001c047e9 in btr_estimate_n_rows_in_range_low (index=0x7fff0494e320, tuple1=0x7fff04a619b0, mode1=PAGE_CUR_GE, tuple2=0x7fff04a61a40, mode2=PAGE_CUR_G, nth_attempt=1)
    at /cdh/mysqldebug/percona-server-5.7.29-32/storage/innobase/btr/btr0cur.cc:5913
#2  0x0000000001c05239 in btr_estimate_n_rows_in_range (index=0x7fff0494e320, tuple1=0x7fff04a619b0, mode1=PAGE_CUR_GE, tuple2=0x7fff04a61a40, mode2=PAGE_CUR_G)
    at /cdh/mysqldebug/percona-server-5.7.29-32/storage/innobase/btr/btr0cur.cc:6248
#3  0x0000000001981cd7 in ha_innobase::records_in_range (this=0x7fff04954b00, keynr=1, min_key=0x7fffe8d3dc00, max_key=0x7fffe8d3dc20)
    at /cdh/mysqldebug/percona-server-5.7.29-32/storage/innobase/handler/ha_innodb.cc:15147
#4  0x0000000000ec2adb in handler::multi_range_read_info_const (this=0x7fff04954b00, keyno=1, seq=0x7fffe8d3ddb0, seq_init_param=0x7fffe8d3ddf0, n_ranges_arg=0, bufsz=0x7fffe8d3dd00, flags=0x7fffe8d3dd04, 
    cost=0x7fffe8d3e1e0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/handler.cc:6716
#5  0x0000000000ec4364 in DsMrr_impl::dsmrr_info_const (this=0x7fff04954f70, keyno=1, seq=0x7fffe8d3ddb0, seq_init_param=0x7fffe8d3ddf0, n_ranges=0, bufsz=0x7fffe8d3e2e0, flags=0x7fffe8d3e2e4, 
    cost=0x7fffe8d3e1e0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/handler.cc:7391
#6  0x000000000198cbc1 in ha_innobase::multi_range_read_info_const (this=0x7fff04954b00, keyno=1, seq=0x7fffe8d3ddb0, seq_init_param=0x7fffe8d3ddf0, n_ranges=0, bufsz=0x7fffe8d3e2e0, flags=0x7fffe8d3e2e4, 
    cost=0x7fffe8d3e1e0) at /cdh/mysqldebug/percona-server-5.7.29-32/storage/innobase/handler/ha_innodb.cc:23185
#7  0x0000000001733252 in check_quick_select (param=0x7fffe8d3e550, idx=0, index_only=false, tree=0x7fff04a26af0, update_tbl_stats=true, mrr_flags=0x7fffe8d3e2e4, bufsize=0x7fffe8d3e2e0, cost=0x7fffe8d3e1e0)
    at /cdh/mysqldebug/percona-server-5.7.29-32/sql/opt_range.cc:10099

二、唯一索引的特別執(zhí)行計劃

root@localhost:test:06:04:57>select *from t_un;
+----+------+---------+
| id | id2 | name |
+----+------+---------+
| 1 | 1 | NULL |
| 2 | 2 | NULL |
| 3 | 3 | NULL |
| 4 | 4 | NULL |
| 5 | 5 | gaopeng |
+----+------+---------+
5 rows in set (2.74 sec)

但是實際都是做的唯一索引霎挟,不會導(dǎo)致全表掃描窝剖。

測試:
id2是唯一索引

root@localhost:test:06:04:57>select *from t_un;
+----+------+---------+
| id | id2 | name |
+----+------+---------+
| 1 | 1 | NULL |
| 2 | 2 | NULL |
| 3 | 3 | NULL |
| 4 | 4 | NULL |
| 5 | 5 | gaopeng |
+----+------+---------+
5 rows in set (2.74 sec)

  • 唯一索引沒有適合的值
    root@localhost:test:05:56:54>desc select *from t_un where id2=10 ;
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
    | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | no matching row in const table |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
    1 row in set, 1 warning (1.75 sec)
  • 唯一索引有適合的值,但是where條件過濾掉了
    root@localhost:test:05:57:03>desc select *from t_un where id2=1 and name='test' ;
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------+
    | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |
    +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------+
    1 row in set, 1 warning (2.18 sec)

ERROR:
No query specified

我看了交互信息酥夭,只看到一條數(shù)據(jù)赐纱,所以這種情況實際上也是用的唯一索引沒有問題。

實際訪問數(shù)據(jù)棧

#0  row_search_mvcc (buf=0x7fff0576e210 "\376\001", mode=PAGE_CUR_GE, prebuilt=0x7fff0414dc80, match_mode=1, direction=0) at /cdh/mysqldebug/percona-server-5.7.29-32/storage/innobase/row/row0sel.cc:4755
#1  0x0000000001978a27 in ha_innobase::index_read (this=0x7fff0576eb00, buf=0x7fff0576e210 "\376\001", key_ptr=0x7fff057746e0 "", key_len=5, find_flag=HA_READ_KEY_EXACT)
    at /cdh/mysqldebug/percona-server-5.7.29-32/storage/innobase/handler/ha_innodb.cc:9970
#2  0x0000000000ec9c08 in handler::index_read_map (this=0x7fff0576eb00, buf=0x7fff0576e210 "\376\001", key=0x7fff057746e0 "", keypart_map=1, find_flag=HA_READ_KEY_EXACT)
    at /cdh/mysqldebug/percona-server-5.7.29-32/sql/handler.h:2990
#3  0x0000000000ec576f in handler::index_read_idx_map (this=0x7fff0576eb00, buf=0x7fff0576e210 "\376\001", index=1, key=0x7fff057746e0 "", keypart_map=1, find_flag=HA_READ_KEY_EXACT)
    at /cdh/mysqldebug/percona-server-5.7.29-32/sql/handler.cc:8051
#4  0x0000000000ebb3b2 in handler::ha_index_read_idx_map (this=0x7fff0576eb00, buf=0x7fff0576e210 "\376\001", index=1, key=0x7fff057746e0 "", keypart_map=1, find_flag=HA_READ_KEY_EXACT)
    at /cdh/mysqldebug/percona-server-5.7.29-32/sql/handler.cc:3336
#5  0x00000000014862a9 in read_const (table=0x7fff0546eb00, ref=0x7fff05773b50) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_executor.cc:2020
#6  0x0000000001485d8c in join_read_const_table (tab=0x7fff05773a80, pos=0x7fff05773c18) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_executor.cc:1905
#7  0x00000000014b1aeb in JOIN::extract_func_dependent_tables (this=0x7fff05773498) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_optimizer.cc:5645
#8  0x00000000014b058d in JOIN::make_join_plan (this=0x7fff05773498) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_optimizer.cc:5109
#9  0x00000000014a4d06 in JOIN::optimize (this=0x7fff05773498) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_optimizer.cc:394
#10 0x000000000151f92b in st_select_lex::optimize (this=0x7fff04005d50, thd=0x7fff04000bf0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_select.cc:1018
#11 0x000000000151e053 in handle_query (thd=0x7fff04000bf0, lex=0x7fff040032a0, result=0x7fff04007ba8, added_options=0, removed_options=0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_select.cc:172
#12 0x00000000014d1e8d in execute_sqlcom_select (thd=0x7fff04000bf0, all_tables=0x7fff04006fd0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_parse.cc:5490
#13 0x00000000014cb119 in mysql_execute_command (thd=0x7fff04000bf0, first_level=true) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_parse.cc:3016
#14 0x00000000014d2e1b in mysql_parse (thd=0x7fff04000bf0, parser_state=0x7fffe8d424a0, update_userstat=false) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_parse.cc:5927
#15 0x00000000014c7a55 in dispatch_command (thd=0x7fff04000bf0, com_data=0x7fffe8d42c90, command=COM_QUERY) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_parse.cc:1539
#16 0x00000000014c688a in do_command (thd=0x7fff04000bf0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/sql_parse.cc:1060
#17 0x00000000015fab28 in handle_connection (arg=0x3443230) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/conn_handler/connection_handler_per_thread.cc:325
#18 0x00000000018cad34 in pfs_spawn_thread (arg=0x3dd00c0) at /cdh/mysqldebug/percona-server-5.7.29-32/storage/perfschema/pfs.cc:2198
#19 0x00007ffff7bc6e65 in start_thread () from /lib64/libpthread.so.0
#20 0x00007ffff5fa088d in clone () from /lib64/libc.so.6
(gdb) c
Continuing.

Breakpoint 7, handler::multi_range_read_info_const (this=0x7fff0576eb00, keyno=2, seq=0x7fffe8d3ddb0, seq_init_param=0x7fffe8d3ddf0, n_ranges_arg=0, bufsz=0x7fffe8d3dd00, flags=0x7fffe8d3dd04, 
    cost=0x7fffe8d3e1e0) at /cdh/mysqldebug/percona-server-5.7.29-32/sql/handler.cc:6651
6651      ha_rows rows, total_rows= 0;

深入理解MySQL主從原理:http://www.reibang.com/nb/43148932
個人微信:gaopp_22389860

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末熬北,一起剝皮案震驚了整個濱河市疙描,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蒜埋,老刑警劉巖淫痰,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異整份,居然都是意外死亡待错,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門烈评,熙熙樓的掌柜王于貴愁眉苦臉地迎上來火俄,“玉大人,你說我怎么就攤上這事讲冠」峡停” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵竿开,是天一觀的道長谱仪。 經(jīng)常有香客問我,道長否彩,這世上最難降的妖魔是什么疯攒? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮列荔,結(jié)果婚禮上敬尺,老公的妹妹穿的比我還像新娘。我一直安慰自己贴浙,他們只是感情好砂吞,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著崎溃,像睡著了一般蜻直。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天袭蝗,我揣著相機與錄音唤殴,去河邊找鬼。 笑死到腥,一個胖子當著我的面吹牛朵逝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乡范,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼配名,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了晋辆?” 一聲冷哼從身側(cè)響起渠脉,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瓶佳,沒想到半個月后芋膘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡霸饲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年为朋,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厚脉。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡习寸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出傻工,到底是詐尸還是另有隱情霞溪,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布中捆,位于F島的核電站鸯匹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏泄伪。R本人自食惡果不足惜殴蓬,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望臂容。 院中可真熱鬧,春花似錦根蟹、人聲如沸脓杉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽球散。三九已至,卻和暖如春散庶,著一層夾襖步出監(jiān)牢的瞬間蕉堰,已是汗流浹背凌净。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留屋讶,地道東北人冰寻。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像皿渗,于是被迫代替她去往敵國和親斩芭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348