2012-12-20 205 views
2

想用索引優化MySQL查詢(或實際上,查詢本身)會有一些幫助。優化查詢

表結構:

CREATE TABLE IF NOT EXISTS `match_current` (
    `partnership_id` int(11) NOT NULL AUTO_INCREMENT, 
    `runs` int(5) NOT NULL DEFAULT '0', 
    `balls` int(5) NOT NULL DEFAULT '0', 
    `user1_id` bigint(11) NOT NULL, 
    `user1_firstname` char(20) NOT NULL, 
    `user1_lastname` char(20) NOT NULL, 
    `user1_runs` int(5) NOT NULL DEFAULT '0', 
    `user1_balls` int(5) NOT NULL DEFAULT '0', 
    `user1_strike` tinyint(1) NOT NULL DEFAULT '1', 
    `user1_out` tinyint(1) NOT NULL DEFAULT '0', 
    `user1_retired` tinyint(1) NOT NULL DEFAULT '0', 
    `user2_id` bigint(11) NOT NULL, 
    `user2_firstname` char(20) NOT NULL, 
    `user2_lastname` char(20) NOT NULL, 
    `user2_runs` int(5) NOT NULL DEFAULT '0', 
    `user2_balls` int(5) NOT NULL DEFAULT '0', 
    `user2_strike` tinyint(1) NOT NULL DEFAULT '0', 
    `user2_out` tinyint(1) NOT NULL DEFAULT '0', 
    `user2_retired` tinyint(1) NOT NULL DEFAULT '0', 
    `last_over` char(15) NOT NULL, 
    `ball_by_ball` varchar(1000) NOT NULL, 
    `facebook` tinyint(1) NOT NULL DEFAULT '0', 
    `friends` tinyint(1) NOT NULL DEFAULT '0', 
    `nudge` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `started` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `status` tinyint(1) NOT NULL DEFAULT '1', 
    `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`partnership_id`), 
    UNIQUE KEY `user1_id_2` (`user1_id`,`user2_id`,`facebook`), 
    KEY `user2_id` (`user2_id`), 
    KEY `user1_id` (`user1_id`), 
    KEY `facebook` (`facebook`), 
    KEY `status` (`status`), 
    KEY `friends` (`friends`), 
    KEY `timestamp` (`timestamp`), 
    KEY `user1_id_3` (`user1_id`,`user1_strike`), 
    KEY `user2_id_2` (`user2_id`,`user2_strike`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=36139 ; 

示例查詢:

SELECT * 
FROM match 
WHERE status = 1 
AND (
    (user1_id=1234 AND user1_strike=1) OR 
    (user2_id=4321 AND user2_strike=1) 
) 
ORDER BY timestamp ASC 

查詢顯然作品,並沒有做太糟糕了,但我們真正增加的流量最近,現在我可以看到它的開始要奮鬥。

乾杯!

+4

爲了優化它,人們還需要知道表結構/索引是什麼。考慮在你的問題中添加「SHOW CREATE TABLE match」的輸出。 – Andris

+0

您想在哪些列上設置索引?索引是用於字符串數組和搜索,而不是用於數字或日期時間列... – shadyyx

+0

您需要向我們展示您擁有的索引。 – paulgrav

回答

0

你真的需要一切嗎?

SELECT * 

創建索引,WHERE子句

INDEX(user1_id, user1_strike, user2_id, user2_strike) 

你也可以包括timestemp並設置順序對於ASC在索引中。

除了這些可能數據庫的表需要額外的索引和可能重新設計。另外考慮檢查SQL服務器設置(使用InnoDB表格,併爲服務器設置正確的緩存/內存限制)。

+1

這是一個想法,讓我們把一個索引放在廚房的水槽上。 –

2

優化查詢時要記住的一件事是,MySQL在執行查詢時只會選擇一個索引;盲目地索引任何你能想到的字段組合都可能沒有多大幫助,並且實際上會降低插入速度。

這看起來像是一個典型的表格,有兩名球員組成一個團隊,因爲您不確定被查詢的用戶是在user1還是user2中搜索這兩者。這很可能會導致所有密鑰被拒絕,並因此執行表掃描。

我的建議是稍微非規範化的表並創建您存儲(user_id, partnership_id)再加上橫跨主鍵單獨的表,在partnerships每個記錄是兩個記錄在此表中;這消除了OR,您可以使用簡單的JOIN從更大的表中獲取所需的信息。

爲了幫助您調查這些問題,您可以使用EXPLAIN <query>來查看MySQL如何「攻擊」您的查詢。