[英]mysql query optimization (wrong indexes?) avoid filesort
我會盡力向自己解釋。 我有一個名為“ artikli”的數據庫,其中包含大約100萬條記錄。 在此表上,我運行許多不同的查詢,但是當存在ORDER by時,有1種查詢會引起問題(較長的執行時間)。
這是我的表結構:
CREATE TABLE IF NOT EXISTSartikli
(id
int(11) NOT NULL,name
varchar(250) NOT NULL,datum
datetime NOT NULL,kategorije_id
int(11) default NULL,id_valute
int(11) default NULL,podogovoru
int(1) default '0',cijena
decimal(10,2) default NULL,valuta
int(1) NOT NULL default '0',cijena_rezerva
decimal(10,0) NOT NULL,cijena_kupi
decimal(10,0) default NULL,cijena_akcija
decimal(10,2) NOT NULL,period
int(3) NOT NULL default '30',dostupnost
enum('svugdje','samobih','samomojgrad','samomojkanton') default 'svugdje',zemlja
varchar(10) NOT NULL,slike
varchar(500) NOT NULL,od_s
varchar(34) default NULL,od_id
int(10) unsigned default NULL,vrsta
int(1) default '0',trajanje
datetime default NULL,izbrisan
int(1) default '0',zakljucan
int(1) default '0',prijava
int(3) default '0',izdvojen
decimal(1,0) NOT NULL default '0',izdvojen_kad
datetime NOT NULL,izdvojen_datum
datetime NOT NULL,sajt
int(1) default '0', PRIMARY KEY (id
), KEYbrend
(brend
), KEYkanton
(kanton
), KEYdatum
(datum
), KEYcijena
(cijena
), KEYkategorije_id
(kategorije_id
,podogovoru
,sajt
,izdvojen
,izdvojen_kad
,datum
) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這是查詢:
SELECT artikli.datum as brojx,
artikli.izdvojen as i,
artikli.izdvojen_kad as ii,
artikli.cijena as cijena, artikli.name
FROM artikli
WHERE artikli.izbrisan=0 and artikli.prodano!=3
and artikli.zavrseno=0 and artikli.od_id!=0
and (artikli.sajt=0 or (artikli.sajt=1 and artikli.dostupnost='svugdje'))
and kategorije_id IN (18)
ORDER by i DESC, ii DESC, brojx DESC
LIMIT 0,20
我想做的是避免Filesort,這很慢。
如果您提供了查詢的解釋計划,那將是一個很大的幫助。
您為什么認為它是導致問題的文件排序? 查看查詢,您似乎在應用大量過濾-這將大大減少輸出集-但沒有一個可以使用可用索引。
artikli.izbrisan=0 and artikli.prodano!=3
and artikli.zavrseno=0 and artikli.od_id!=0
and (artikli.sajt=0 or (artikli.sajt=1 and artikli.dostupnost='svugdje'))
and kategorije_id IN (18)
盡管我不知道您的數據的模式是什么,但我懷疑通過在上添加索引,您可能會獲得更多好處:
kategorije_id,izbrisan,sajt
所有其他索引是否真的已經被使用?
盡管你會通過非規范化所有這些布爾得到您的降壓很多更多的收益(假設表是標准化入手,有沒有隱藏的功能依賴於那里)。
C。
問題是您在ORDER BY
使用的izdvojen
, izdvojen_kad
和datum
列上沒有索引。
請注意,您以kategorije_id
開頭的大索引不能用於排序(盡管它對where子句有所幫助),因為排序所依據的列位於索引的末尾。
實際上,排序依據不是您想要的索引的基礎...而是您要與查詢基本匹配的CRITERIA ...過濾掉較小的數據集,您將獲得較小的表集...我會稍微更改WHERE子句,但是您將最了解您的數據。 首先將最小的期望條件放在首位,並確保以此為基礎的索引...類似
WHERE
artikli.izbrisan = 0
and artikli.zavrseno = 0
and artikli.kategorije_id IN (18)
and artikli.prodano != 3
and artikli.od_id != 0
and ( artikli.sajt = 0
or ( artikli.sajt = 1
and artikli.dostupnost='svugdje')
)
並具有(izbrisan,zavrseno,kategorije_id)的復合索引...我已將其他!=比較設置為模式,因為它們不是特定的鍵值,相反,它們都是除所討論的值之外的所有值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.