2016-07-29 74 views
2

我必须在超过1000万行的表上运行查询。 表结构是索引多列

user(varchar 100), 
played(int 11), 
won(int 11), 
lost(int 11), 
drawn(int 11), 
user1(varchar 30), 
user2(varchar 30). 


Where 
User - primary key 
user1 - index 
user2 - index 

MySql数据库引擎是MyISAM的。

我的问题是 - 当我运行下面的查询它正在采取超过17秒。

SELECT * FROM h2hstats 
WHERE (won+lost+drawn) > 5 
    AND (user1 = '717054941' OR user2 = '717054941') 

如何缩短执行时间?

我会在(won + lost + drawn)列上做另一个索引吗?

+0

不,因为你不寻找他们。一旦条件满足,您可以访问数据。所以它取决于user1和user2的正确索引。对于只包含数值的列使用数值字段类型(INTEGER或BIGINT)也会使性能受益。 – syck

+1

之前,但也许从来没有做过这种方式是这样的: 和717054941 IN(用户1,用户2) – Jeff

+0

我建议创建在Win计算索引+最后得出+ ..http://dev.mysql.com/doc/refman/5.7 /en/generated-column-index-optimizations.html ..进一步我不知道如何使用两个单独的索引(用户1,用户2) – TheGameiswar

回答

2

首先,如果用户列是数字,那么不要使用单引号作为常量。这可能会混淆优化器。这可能不会帮助你的查询(我的SQL在使用OR索引方面做得不好),但值得一试。

其次,考虑重写查询为:

SELECT * 
FROM h2hstats 
WHERE (won + lost + drawn) > 5 AND user1 = 717054941 
UNION ALL 
SELECT * 
FROM h2hstats 
WHERE (won + lost + drawn) > 5 AND user2 = 717054941 ; 

的MySQL肯定会使用索引的每个子查询。这应该会提高性能。

(注:此版本假定user1 <>user2如果这是可能的,你可能想使用UNION而非UNION ALL。)