这将是其中一个问题,但我需要问一下。
我有一张大表,可能有也可能没有一个唯一行。因此,我需要一个只能告诉我TRUE或FALSE的MySQL查询。
根据我目前的知识,我看到两个选项(伪代码):
[id =主键]
选项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.
出于任何原因,这些中的任何一个是优选的,还是可能有更好的解决方案?
感谢。
答案 0 :(得分: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 :(得分:1)
AFAIK,如果您的ID列上有索引,则两个查询的性能大致相同。第二个查询将在您的程序中减少1行代码,但这也不会对性能产生任何影响。
答案 2 :(得分:1)
我个人通常会先从行中选择id并限制为1行。从编码的角度来看,我更喜欢这个。我只需检查返回的行数,而不必实际检索数据。
如果我要比较速度,我会说不在MySQL中计数会更快。我没有任何证据,但我的猜测是MySQL必须获取所有行,然后计算有多少行。 Altough ......在第二个想法中,它必须在第一个选项中执行此操作,因此代码将知道有多少行。但是,由于你有COUNT(id)
vs COUNT(*)
,我会说might be slightly slower。
答案 3 :(得分:1)
直观地说,第一个可能更快,因为它可以在找到第一个值时中止表(或索引)扫描。但是你应该检索x而不是id,因为如果引擎在x上使用索引,则不需要转到行实际所在的块。
另一种选择可能是:
select exists(select 1 from mytable where x = ?) from dual
已经返回一个布尔值。
答案 4 :(得分:0)
通常,您使用group by having
子句来确定表中是否存在重复的行。如果你有一个带有id和名字的表。 (假设id是主键,并且您想知道名称是唯一的还是重复的)。你会用
select name, count(*) as total from mytable group by name having total > 1;
以上将返回重复的名称数和次数。
如果您只想让一个查询将您的答案设为真或假,则可以使用嵌套查询,例如
select if(count(*) >= 1, True, False) from (select name, count(*) as total from mytable group by name having total > 1) a;
如果你的表有重复行,则上面应该返回true,否则返回false。