[英]Optimizing MySQL table index/query
我有一個查詢,大約需要19秒鍾才能運行,這很長一段時間。
這是我的慢日志的結果:
# Query_time: 19.421110 Lock_time: 0.000171 Rows_sent: 6 Rows_examined: 48515488
use c3_xchngse;
SET timestamp=1398891560;
SELECT *
FROM rates
WHERE id IN (
SELECT Max(id)
FROM rates
WHERE LOWER(`currency`) = LOWER('eur')
GROUP BY bankId
);
我試圖添加索引,例如:
ALTER TABLE `c3_xchngse`.`rates` ADD INDEX `searchIndex` ( `id` , `currency` , `bankId` )
但是它似乎並沒有優化查詢,它們一直持續很長時間。 我也嘗試為上面查詢中解決的每一列添加單獨的索引,但是那里也沒有幫助。
這是我的表,今天包含大約7000行:
CREATE TABLE IF NOT EXISTS `rates` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`bankId` int(11) NOT NULL,
`currency` varchar(3) NOT NULL,
`buy` double NOT NULL,
`sell` double NOT NULL,
`addDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`since` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `Unique` (`bankId`,`currency`,`since`),
KEY `bankId` (`bankId`),
KEY `currency` (`currency`),
KEY `searchIndex` (`id`,`currency`,`bankId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='The rates' AUTO_INCREMENT=6967 ;
如何優化查詢或優化表並獲得完全相同的結果,但速度更快?
使用LOWER(currency)會使索引無用。
標准化表中的數據:
UPDATE rates SET currency = LOWER(currency) WHERE 1;
並確保傳遞給查詢的所有參數在命中查詢之前都被轉換為小寫。
另外,您可以將貨幣字段設置為ENUM類型以幫助進行內部索引編制: https : //dev.mysql.com/doc/refman/5.0/en/enum.html
這是使用所述查詢的重寫join
(其有時可以是有益的):
select r.*
from rates r join
(select max(id)
from rates
where `currency` = 'Eur'
group by bankId
) rmax
on r.id = rmax.id;
請注意,如Noah所建議的,刪除了lower()
。 如果您有區分大小寫的排序規則,請確保大小寫正確。 不要圍繞currency
發揮作用; 排除了索引的使用。 為此所需的索引是rates(currency, bankId, id)
。
你正在努力尋找所有的最大速率信息id
對每個銀行eur
。 您也可以使用not exists
來表達這一點:
select r.*
from rates r
where not exists (select 1
from rates r2
where r2.bankid = r.bankid and
r2.currency = 'Eur' and
r2.id > r.id
);
使用rates(bankid, currency, id)
索引rates(bankid, currency, id)
可能會更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.