2010-02-21 78 views
2

这将是其中一个问题,但我需要问一下。MySQL:SELECT(x)WHERE vs COUNT WHERE?

我有一张大桌可能有或没有一个独特的行。因此,我需要一个MySQL查询,它会告诉我TRUE或FALSE。

用我的当前的知识,我看到两个选项(伪码):

[ID =主键]

OPTION 1:

SELECT id FROM table WHERE x=1 LIMIT 1 
... and then determine in PHP whether a result was returned. 

选项2:

SELECT COUNT(id) FROM table WHERE x=1 
... and then just use the count. 

无论是出于任何原因,这些都是可取的,还是有可能是更好的解决方案?

谢谢。

回答

3

如果选择标准是真正唯一的(即最多得到一个结果),那么通过在该标准中包含一列(或多列)的索引,您将看到大规模的性能改进。

create index my_unique_index on table(x) 

如果要强制唯一性,甚至不是一种选择,你必须有

create unique index my_unique_index on table(x) 

有了这个索引,查询的唯一标准,将执行得非常好,无论未成年SQL的调整像count(*),count(id),count(x),limit 1等等。 为清楚起见,我会写

select count(*) from table where x = ? 

我会避免LIMIT 1其他两个原因:

  • 这是非标准SQL。我对此没有信心,在必要时使用MySQL特有的东西(即用于分页数据),但这里没有必要。
  • 如果由于某种原因,您有多行数据,这可能是您应用程序中的一个严重错误。有了LIMIT 1,你永远不会看到问题。这就像计算侏罗纪公园中的恐龙数量,假设这个数字只有可能下降。
+0

对于侏罗纪公园的类比。我可能会偷走它。对于其余论点的赞成 - 我完全同意。 – 2010-02-21 07:30:17

+0

感谢您的回答,尽管我喜欢使用LIMIT 1.非标准SQL不会打扰我(只要它有效),而对于第二个参数,在我的应用程序中看到这样的错误几乎与恐龙复活。 :) – Tom 2010-02-21 15:27:06

1

AFAIK,如果您的ID列上有索引,那么这两个查询的性能会差不多。第二个查询在你的程序中需要少一行代码,但这也不会对性能产生影响。

+0

ID列上的索引在这里没什么大不了,OP想要X上的索引。 – Thilo 2010-02-21 06:15:24

+0

噢,对不起,这是X – e4c5 2010-02-21 08:09:43

0

通常,您使用group by having子句来确定表中是否存在重复行。如果你有一个带有id和名字的表格。 (假设id是主键,并且您想知道名称是唯一的还是重复的)。您可以使用

select name, count(*) as total from mytable group by name having total > 1; 

以上将返回重复名称的数量和次数。

如果您只想让一个查询将您的答案设为true或false,则可以使用嵌套查询,例如,

select if(count(*) >= 1, True, False) from (select name, count(*) as total from mytable group by name having total > 1) a; 

上面应该返回true,如果你的表有重复行,否则为false。

+1

因为他正在做极限1,我怀疑OP是在寻找重复。 – Thilo 2010-02-21 06:35:46

1

就我个人而言,我通常会做第一次从行中选择id并限制为1行。我从编码的角度来看更好。不必实际检索数据,我只需检查返回的行数。

如果我要比较速度,我会说在MySQL中不做计数会更快。我没有任何证据,但我的猜测是,MySQL必须获得所有行,然后统计有多少行。 Altough ...在第二个想法中,它也必须在第一个选项中这样做,所以代码也会知道有多少行。但既然你有COUNT(id)COUNT(*),我会说它might be slightly slower

1

直观上,第一个可能会更快,因为它可以在找到第一个值时中止表(或索引)扫描。但是您应该检索x not id,因为如果引擎使用x上的索引,则不需要转到实际所在行的块。

另一种选择可能是:

select exists(select 1 from mytable where x = ?) from dual 

这已经返回一个布尔值。