2012-05-22 200 views
17

我们在MySQL内部连接中遇到了一些奇怪的问题。基本上,我们在使用'='运算符时会遇到奇怪的错误,但是使用'like'会使它工作。不幸的是,这是通过ActiveRecord,而不是简单的方法,只是在那里巴掌'喜欢',而我们想知道这里实际发生了什么。MySQL INNER JOIN - '='vs'like'

这里是一个失败的查询:

mysql> SELECT COUNT(*) FROM `versions` INNER JOIN `site_versions` 
       ON `versions`.id = `site_versions`.version_id; 

以下是错误:

ERROR 1296 (HY000): Got error 20008 'Query aborted due to out of query memory' 
from NDBCLUSTER 

这里是工作的查询:

mysql> SELECT COUNT(*) FROM `versions` INNER JOIN `site_versions` 
       ON `versions`.id like `site_versions`.version_id; 

下面是对一些细节表本身:

mysql> desc site_versions; 
+----------------------+----------+------+-----+---------+----------------+ 
| Field    | Type  | Null | Key | Default | Extra   | 
+----------------------+----------+------+-----+---------+----------------+ 
| id     | int(11) | NO | PRI | NULL | auto_increment | 
| version_id   | int(11) | YES | MUL | NULL |    | 
[..snip..] 
+----------------------+----------+------+-----+---------+----------------+ 

mysql> desc versions; 
+------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+------------+--------------+------+-----+---------+----------------+ 
| id   | int(11)  | NO | PRI | NULL | auto_increment | 
[..snip..] 
+------------+--------------+------+-----+---------+----------------+ 

任何想法为什么'喜欢'的作品和'='不?

+4

就像你期待的结果一样吗?也许它只是没有加入任何东西(因为int的意思是什么?),所以避免了有效查询触发的内存问题。 –

+1

@andrewcooke - 嗯,'like'在使用这种方式时似乎工作:http://sqlfiddle.com/#!2/86792/1 –

+3

它也可以帮助显示每个查询的'解释'的问题。 –

回答

0

不知道这是否能解决您的问题,但这是可能的。请勿使用count(*)。也许它正在为计算什么而变得“困惑”。计算特定领域的最佳做法是id。为此,您需要为表格使用别名。

SELECT COUNT(v.id) FROM versions as v 
INNER JOIN site_versions as sv ON v.id = sv.version_id; 
+1

或者只是使用一个常量:'SELECT COUNT(1)FROM ...' – bjnord

+4

在像OP这样的不寻常的情况下,你不应该对像你这样的建议感到惊讶。我不会。但是这个陈述,*'计算一个特定领域的最佳实践'*,是在另一个领域的背景下做出的,即*'不要使用count(*)''*,这听起来像是至少可以说,未来也是有争议的。使用COUNT(*)来计算组中的行,而不管行中的数据或任何其他条件是否完全有效,并且符合标准。也许在MySQL中有一些含义,但是你可能不得不提到它是如此。 –

+0

@Andriy - 我也总是假设'count(*)'应尽可能避免?虽然语法是有效的,可能与op的问题没有关系,但确实存在[性能明显不同](http://www.mysqlperformanceblog.com/2007/04/10/count-vs-countcol/)。虽然我不是DBA,但是由于开发者总是避免使用“count(*)”。我可能在这里误解了一些东西,如果我这样做,请告诉我。 – stefgosselin

3

讽刺的是,这似乎是与优化;通过使用LIKE,你强制MySQL停止使用可能的索引(至少在数字列中,因为它必须将它们全部转换为字符串以进行比较)。

因此,通过使用=似乎MySQL只是用尽空间(内存/磁盘)来使用索引(检查key_buffer设置)。

当然,这只是一种预感,我对NDB不甚了解,可以进一步帮助您,但我希望这会让您朝着正确的方向前进。