2012-07-09 79 views
1

我有一个mysql数据表,我只需要返回没有“Deactive”状态且没有Total 0的行(但可以有状态为deactive的行和总数不是0,反之亦然)。之前,我需要这个要求,我只是在做标准查询,选择所有行:Mysql查询效率

SELECT * FROM tableName WHERE uid = id; 

但是现在,当我更改查询以加入上述限制:

SELECT * FROM tableName WHERE uid = id AND (status != "Deactive" OR Total != 0); 

这种自下而上查询花费多少更长的时间才能完成。为什么会发生这种情况,有没有更好的方法可以做这个查询?

+0

多少条记录出现在表中你有你要么添加到查询的字段的索引? – Braiba 2012-07-09 22:40:23

+0

是不是你的第二个查询应该是'SELECT * FROM tableName WHERE uid = id AND(status!=“Deactive”OR Total!= 0);'。还要在这些字段中添加索引,您的查询将得到更快执行... – 2012-07-09 22:40:37

+0

只有几千条记录。不,我没有这些属性的任何索引,因为表格不是很大。 – ewein 2012-07-09 22:49:49

回答

2

第一个查询是基于索引查找的(我假设用'uid')。第二个查询正在过滤其他值。运行它,它会帮助你找出你如何才能最好地优化它:

EXPLAIN EXTENDED SELECT * FROM tableName WHERE uid = id AND status != "Deactive" OR Total != 0; 

这是肮脏的,但是这可能会是一个快速的方法来加快速度:

SELECT 
    * 
FROM 
(
    SELECT 
    * 
    FROM 
    tableName 
    WHERE 
    uid = id 
) as temp 
WHERE 
    temp.status != "Deactive" 
    OR temp.Total != 0; 

这将迫使该查询只是首先获取具有匹配的uid的行,然后将其过滤掉,而不必进行大表扫描。就像我之前说过的那样,EXPLAIN EXTENDED是你的朋友

+0

我想如果asker添加了合适的括号,那么没有子查询就会有相同的性能(MySQL会很快放弃不匹配的行)。由于它是(没有parens),因此OR条件可能包含该行,因此在评估Total之前无法消除该行。 – 2012-07-09 22:56:55

-1

你需要返回每一行中的所有数据吗?即只挑选你需要的列将使查询运行得更快。

你也说你需要'返回没有'Deactive'状态并且没有Total'0'的行。然后,您的查询应为:

SELECT * (or column names) FROM tableName WHERE uid = id AND status != "Deactive" AND Total != 0;

+0

不,此查询将删除状态为Deactive或总数为0的所有行。只要总数不为0,我仍然希望状态为Deactive的行。 – ewein 2012-07-09 23:15:49