2012-05-22 4 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

похоже на результаты, которые вы ожидаете? может быть, это просто не может присоединиться к чему-либо (потому что что-то похожее на ints?), и поэтому избегайте проблемы с памятью, вызываемой действительным запросом. –

+1

@andrewcooke - Хм, 'похоже', похоже, работает, когда используется так: 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

1

Я не могу себе представить, как like хорошо работает в этой ситуации, но как насчет просто пытается проверить значение переменной MaxAllocate и увеличить его? Его значение по умолчанию: 32M и может быть увеличено до 1G.

Ссылка: http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxallocate

3

Как ни странно это, кажется, связано с оптимизацией; используя LIKE, вы вынуждаете MySQL останавливать использование возможных индексов (по крайней мере, с числовыми столбцами, потому что для их сравнения нужно привести их все в строку).

Таким образом, используя =, кажется, что MySQL просто исчерпывает пространство (память/диск) для использования индекса (проверьте настройку key_buffer).

Конечно, это только догадка, и я мало знаю о NDB, чтобы помочь вам дальше, но я надеюсь, что это приведет вас в правильном направлении.