2017-08-11 199 views
2

我的表中有200萬條記錄。當我執行具有3 where condition的查詢時,響應時間太長。Mysql執行時間太長

查詢

SELECT COUNT(*) 
    FROM `table` 
WHERE DATE(`created_at`) = '2017-08-11' 
    AND `type` in (4,13,15) 
    AND `status` = 1 

執行時間:3秒

如何可以減少該查詢或任何這樣的查詢的執行時間?

編輯

表模式

CREATE TABLE `transactions` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `type` int(11) NOT NULL, 
    `status` int(11) NOT NULL DEFAULT '2', 
    `created_at` timestamp NULL DEFAULT NULL, 
    ... 
    PRIMARY KEY (`id`), 
    KEY `query` (`created_at`,`type`,`status`), 
    KEY `query2` (`status`,`type`) 

我不知道我的索引是真還是假

+2

你的桌子是怎樣的?我認爲你錯過了幾個'index'es – Fotis

+0

@Fotis它有41列 –

回答

1

嘗試分離IN條款。我有親身經歷的IN子句使查詢變慢,因爲內部MySQL假定全表掃描並在某些情況下忽略索引。另外,DATE(created_at)將在datetime上索引時完全忽略該索引。

你可以試試下面UNION查詢,並希望它的速度輸出:

SELECT SUM(total) AS total 
    FROM (
    SELECT COUNT(*) AS total 
     FROM `table` 
    WHERE `created_at` BETWEEN '2017-08-11 00:00:00' AND '2017-08-11 23:59:59' 
     AND `type` = 4 
     AND `status` = 1 
    UNION 
    SELECT COUNT(*) AS total 
     FROM `table` 
    WHERE `created_at` BETWEEN '2017-08-11 00:00:00' AND '2017-08-11 23:59:59' 
     AND `type` = 13 
     AND `status` = 1 
    UNION 
    SELECT COUNT(*) AS total 
     FROM `table` 
    WHERE `created_at` BETWEEN '2017-08-11 00:00:00' AND '2017-08-11 23:59:59' 
     AND `type` = 15 
     AND `status` = 1 
) z; 

您還可以添加僅包含date列或created_at如果刪除時間,並將其存儲在一個新的time列,現有系統可行。

+0

我有語法錯誤(DATE('created_at'),'type','status')'' –

+1

抱歉我的錯。忙着工作,所以匆忙回覆。沒有注意到索引錯誤。已更新我的帖子。不要改變你的索引。已修改查詢。試試看。 – Samir

+0

非常感謝。執行時間:0.11:| :| :| –

1

爲了使該查詢運行速度更快,你需要爲你的表添加索引。

首先運行相同的查詢,在SELECT之前加入EXPLAIN。這將給你一個很好的概述,檢查了多少行,什麼是關鍵基數等。

如果這是一個標準查詢,我建議你add an index所有3列。如果您計劃單獨查詢列,則可以向需要查詢的每個列添加索引,但不要過度使用表格,因爲表格會變慢。

如果您在添加索引後運行EXPLAIN,您會得到顯着更低的檢查行數。

如果您的表已經有索引,您可以使用USE INDEX提示來提示MySQL服務器。

+0

問題更新 –

0

可能是你需要一個合適的指數例如:

create index my_new_index on `table` (date(`created_at`), `type`, `status`); 
0

替換

query KEY(created_attypestatus

KEY query2statustype

KEY created_atcreated_at

KEY typetype),

KEY statusstatus),

我認爲它將使更快。此外,您必須將類型和狀態的數據類型轉換爲tinyint,smallint,如果可能且應添加無符號約束,則它將永遠不會有符號值。