亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 3662 | 回復: 18
打印 上一主題 下一主題

MySQL 選擇索引疑惑 [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2012-03-28 13:40 |只看該作者 |倒序瀏覽
希望大家指點

表結(jié)構(gòu)如下所示:
mysql> show create table book\G
*************************** 1. row ***************************
     Table: book
Create Table: CREATE TABLE `book` (
`book_id` int(11) NOT NULL AUTO_INCREMENT,
`status` int(11) NOT NULL,
`level` int(11) NOT NULL,
`update_time` datetime DEFAULT NULL,
...... snip .......
PRIMARY KEY (`book_id`),
KEY `S_L_U` (`status`,`level`,`update_time`),
KEY `S_U` (`status`,`update_time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
status 有6個取值,level只有2個取值。該表總共有72550行數(shù)據(jù),status=2的有28527行數(shù)據(jù),level=0的有72330行數(shù)據(jù),level=1的有220行數(shù)據(jù)。

我有個Query是這樣的:
select  update_time from book  where status = 2  order by update_time
desc limit offset,row_count

按照原理,該Query應(yīng)該是使用S_U索引的。
當offset比較小的時候,該Query使用S_U(status,update_time)索引。
mysql> explain select  update_time from book  where status = 2  order
by update_time desc limit 100,50\G
*************************** 1. row ***************************
         id: 1
select_type: SIMPLE
      table: book
       type: range
possible_keys: S_L_U,S_U
        key: S_U
    key_len: 4
        ref: NULL
       rows: 27893
      Extra: Using where; Using index
1 row in set (0.00 sec)

但是隨著offset的增大,該Query會選擇使用S_L_U(status,level,update_time)索引。而且從explain的輸出來看,Extra列顯示還有using
index,但是我strace了這個sql的過程,發(fā)現(xiàn)該Query進行了50次的表數(shù)據(jù)讀取,這個是第一個不理解的地方,還有為啥不選擇S_U索引,S_U索引能夠覆蓋update_time,不是連排序都省了嗎??
mysql> explain select  update_time from book  where status = 2  order
by update_time desc limit 28000,50\G
*************************** 1. row ***************************
         id: 1
select_type: SIMPLE
      table: book
       type: ref
possible_keys: S_L_U,S_U
        key: S_L_U
    key_len: 4
        ref: const
       rows: 19199
      Extra: Using where; Using index; Using filesort
1 row in set (0.00 sec)

mysql> select  update_time from book  where status = 2  order by
update_time desc limit 28000,50;
+---------------------+
| update_time         |
+---------------------+
| 2008-08-11 17:08:17 |
  ...... snip ......
| 2008-08-11 14:00:39 |
+---------------------+
50 rows in set (0.03 sec)

如果使用force index 執(zhí)行使用S_U索引的話,反而沒有使用S_L_U索引速度快,這個是為啥呢?
mysql> explain select  update_time from book force index(S_U) where
status = 2  order by update_time desc limit 28000,50\G
*************************** 1. row ***************************
         id: 1
select_type: SIMPLE
      table: book
       type: ref
possible_keys: S_U
        key: S_U
    key_len: 4
        ref: const
       rows: 27893
      Extra: Using where; Using index
1 row in set (0.00 sec)

mysql> select  update_time from book force index(S_U) where status = 2
order by update_time desc limit 28000,50;
+---------------------+
| update_time         |
+---------------------+
| 2008-08-11 17:08:17 |
...... snip ......
| 2008-08-11 14:00:39 |
+---------------------+
50 rows in set (0.10 sec)

論壇徽章:
4
CU大;照
日期:2013-03-13 15:32:35CU大;照
日期:2013-03-13 15:38:15CU大;照
日期:2013-03-13 15:38:52戌狗
日期:2013-12-27 15:08:11
2 [報告]
發(fā)表于 2012-03-28 14:57 |只看該作者
where條件只有一個status
不用聯(lián)合索引,直接用status做個索引呢
另外order by update_time --這個字段是沒有索引的

論壇徽章:
0
3 [報告]
發(fā)表于 2012-03-28 16:55 |只看該作者
感謝2樓,但是update_time是可以使用索引的。期待其他回答。

論壇徽章:
0
4 [報告]
發(fā)表于 2012-03-28 22:36 |只看該作者
小版主殺手 發(fā)表于 2012-03-28 14:57
where條件只有一個status
不用聯(lián)合索引,直接用status做個索引呢
另外order by update_time --這個字段是 ...


status要和update_time做個聯(lián)合索引。

否則在status和update_time分別單獨建立個索引,

會先選擇索引status把記錄掃描出來,然后對字段update_time逐行進行排序操作。

用explain優(yōu)化器查看,應(yīng)該會出現(xiàn)Using filesort

論壇徽章:
4
CU大;照
日期:2013-03-13 15:32:35CU大;照
日期:2013-03-13 15:38:15CU大牛徽章
日期:2013-03-13 15:38:52戌狗
日期:2013-12-27 15:08:11
5 [報告]
發(fā)表于 2012-03-29 11:00 |只看該作者
yuanxb1985 發(fā)表于 2012-03-28 16:55
感謝2樓,但是update_time是可以使用索引的。期待其他回答。


記得手冊上有關(guān)于優(yōu)化器的選擇介紹

每個表的索引被查詢,并且使用最好的索引,除非優(yōu)化器認為使用表掃描更有效。是否使用掃描取決于是否最好的索引跨越超過30%的表。優(yōu)化器更加復雜,其估計基于其它因素,例如表大小、行數(shù)和I/O塊大小,因此固定比例不再決定選擇使用索引還是掃描。

論壇徽章:
6
數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2015-10-11 06:20:00數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2015-10-12 06:20:00數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2015-10-15 06:20:00數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2015-10-30 06:20:00綜合交流區(qū)版塊每月發(fā)帖之星
日期:2015-12-02 14:59:01數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2015-12-15 06:20:00
6 [報告]
發(fā)表于 2012-03-29 11:29 |只看該作者
try:
  1. explain select  update_time from book  where status = 2  order by
  2. update_time desc,status desc  limit 28000,50;
復制代碼

論壇徽章:
0
7 [報告]
發(fā)表于 2012-03-29 19:04 |只看該作者
只要有ORDER BY ,MYSQL就會用臨時表!ODERY BY 中的字段用不到索引中!
為什么用S_L_U是因為MYSQL會選擇最優(yōu)的索引來查詢!最優(yōu)的索引一般都會看影響的行數(shù)!
S_L_U影響的行數(shù)明顯比S_U少!

你可以再加個status索引看看!

論壇徽章:
0
8 [報告]
發(fā)表于 2012-03-30 09:55 |只看該作者
提示: 作者被禁止或刪除 內(nèi)容自動屏蔽

論壇徽章:
0
9 [報告]
發(fā)表于 2012-03-30 10:05 |只看該作者
首先謝謝你的回復。但是,你的說法是不對的。請自行查看手冊相應(yīng)說明。回復 7# witer666


   

論壇徽章:
0
10 [報告]
發(fā)表于 2012-03-30 10:08 |只看該作者
首先感謝回復。另外,建立單個update_time索引,是可以對order by update_time 的排序做優(yōu)化,但是當order by 和 limit一起使用,尤其是在offset較大的時候,使用索引排序,不如全表掃描的性能好。回復 8# kerlion


   
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP