mysql 5.6.30由於爬蟲抓取的資料不斷增多,這兩天在不斷對資料庫以及查詢語句進行優化,其中乙個表結構如下:
create
table
`news*****_article` (
`id`
varchar(50) not
null comment '編號',
`title`
varchar(190) not
null comment '標題',
`author`
varchar(255) default
null comment '作者',
`date`
date
null
default
null comment '發表時間',
`content` longtext comment '正文',
`status` tinyint(4) default
'0',
primary
key (`id`),
key`idx_status_date` (`status`,`date`)
) engine=innodb default charset=utf8mb4 comment='文章表';
根據業務需要,新增了idx_status_date
索引,在執行下面這個 sql 時特別耗時:
select id, title, status, date
from article where status > -2
anddate = '2016-01-07';
根據觀察,每天新增的資料大概在2500條以內,本以為這裡指定了具體某天的日期'2016-01-07'
,實際需要掃瞄的資料量應該在2500條以內才對,但實際並非如此:
實際共掃瞄了185589條資料,遠遠高於預估的2500條,且實際執行時間都將近3秒鐘:
這是為什麼呢?
將idx_status_date (status, date)
改為idx_status (status)
後,檢視 mysql 執行計畫:
可以看到將多列索引改為單列索引後,執行計畫要掃瞄的資料總量沒有任何變化。結合多列索引遵循最左字首原則,推測上面的查詢語句只使用了idx_status_date
最左邊的status
的索引。
翻了下《高效能mysql》找到了下面這段話,證實了我的想法:
如果查詢中有某個列的範圍查詢,則其右邊所有列都無法使用索引優化查詢。例如有查詢因此,這裡解決思路有兩種:where last_name = 'smith' and first_name like 'j%' and dob = '1976-12-23'
,這個查詢只能使用索引的前兩列,因為這裡like
是乙個範圍條件(但是伺服器可以把其餘列用於其他目的)。如果範圍查詢列值的數量有限,那麼可以通過使用多個等於條件來代替範圍條件。
優化後的執行計畫:
實際執行結果:
當人們談論索引的時候,如果沒有特別指明型別,那麼多半說的是b-tree
索引,它使用b-tree
資料結構來儲存資料。我們使用術語「b-tree」,是因為 mysql 在create table
和其他語句中也使用該關鍵字。不過,底層的儲存引擎也可能使用不同的儲存結構。innodb使用的是b+tree。
假如有如下資料表:
create
table people (
last_name varchar(50) not
null,
first_name varchar(50) not
null,
dob date
notnull,
gender enum('m', 'f') not
null,
key(last_name, first_name, dob)
);
mysql多列索引 MySQL的多列索引
什麼是索引?索引用來快速地尋找那些具有特定值的記錄,所有mysql索引都以b 樹的形式儲存。如果沒有索引,執行查詢時mysql必須從第乙個記錄開始掃瞄整個表的所有記錄,直至找到符合要求的記錄。表裡面的記錄數量越多,這個操作的代價就越高。如果作為搜尋條件的列上已經建立了索引,mysql無需掃瞄任何記錄...
MySql多列索引
多列索引 多列索引就是將多個列作為乙個索引,在乙個多列b tree索引中,索引列的順序意味著索引首先按照最左列進行排序,然後第二列第三列等等。所以可以按照公升序或者降序進行掃瞄,以滿足精確符合列順序的order by,group by和distinct等子句,所以,多列索引的順序至關重要,key 列...
mysql多列索引
1,資料庫每次查詢只能使用乙個索引 2,假設資料 表t a,b,c rowid 為物理位置 rowid a b c 1 1 1 1 2 2 1 13 3 2 2 14 4 1 3 3 5 2 3 12 6 1 2 5 7 2 3 9 8 1 2 2 9 1 3 6 10 2 2 11 11 2 2 ...