2012-12-20 208 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如何“攻击”您的查询。