Какое ограничение размера для IN и NOT IN в MySQL - PullRequest
10 голосов
/ 17 января 2009

В приложении возникает исключение из памяти, когда условие IN или NOT IN очень большое. Я хотел бы знать, что является ограничением для этого.

Ответы [ 6 ]

8 голосов
/ 17 января 2009

Возможно, вам лучше воспользоваться другим способом выполнения запроса?

Я предлагаю вам загрузить значения совпадений в таблицу с одним столбцом, а затем выполнить внутреннее соединение столбца, запрашиваемого в одном столбце новой таблицы.

Вместо

SELECT a, b, c FROM t1 WHERE d in (d1, d2, d3, d4, ...)

построить временную таблицу с 1 столбцом, назовите ее "dval"

dval  
----  
 d1  
 d2  
 d3
SELECT a, b, c FROM t1  
INNER JOIN temptbl ON t1.d = temptbl.dval
4 голосов
/ 17 января 2009

Необходимость спрашивать об ограничениях, когда выполнение SQL-запроса или разработка базы данных является хорошим индикатором того, что вы делаете это неправильно.

3 голосов
/ 19 января 2009

Я всегда использую IN и NOT IN, когда условие очень мало (менее 100 строк или около того). Это хорошо работает в этих сценариях. Я использую OUTER JOIN, когда условие большое, так как запрос не должен искать условие «IN» для каждого кортежа. Вам просто нужно проверить таблицу, из которой вы хотите получить все строки.

Для "IN" условие соединения НЕ НУЛЬ

Для «НЕ В» условие соединения НЕДЕЙСТВИТЕЛЕНО

, например

/* Get purchase orders that have never been rejected */
SELECT po.*
FROM PurchaseOrder po LEFT OUTER JOIN 
     (/* Get po's that have been rejected */
     SELECT po.PurchaesOrderID
     FROM PurchaseOrder po INNER JOIN 
         PurchaseOrderStatus pos ON po.PurchaseOrderID = pos.PurchaseOrderID
     WHERE pos.Status = 'REJECTED'
     ) por ON po.PurchaseOrderID = por.PurchaseOrderID
WHERE por.PurchaseOrderID IS NULL    /* We want NOT IN */
1 голос
/ 06 сентября 2009

У меня похожая проблема, но я только передаю 100 3-значных идентификаторов в моем предложении IN. Когда я смотрю на трассировку стека, на самом деле это обрезает отдельные значения запятых в предложении IN. Я просто не получаю все результаты для возврата. У кого-нибудь была такая проблема раньше? Если она уместна, я использую фреймворк Symfony ... Я проверяю, не является ли это проблемой Propel, но я просто хотел чтобы увидеть, может ли это быть sql

0 голосов
/ 17 января 2009

Я не знаю, каков предел, но я сталкивался с этой проблемой и раньше. Мне пришлось переписать мой запрос примерно так:

select * from foo
  where id in (select distinct foo_id from bar where ...)
0 голосов
/ 17 января 2009

Я использовал IN с довольно большими списками идентификаторов - я подозреваю, что проблема с памятью не в самом запросе. Как вы получаете результаты?

Этот запрос, например, с живого сайта:

SELECT DISTINCT c.id, c.name FROM categories c 
LEFT JOIN product_categories pc ON c.id = pc.category_id 
LEFT JOIN products p ON p.id = pc.product_id 
WHERE p.location_id IN (
955,891,901,877,736,918,900,836,846,914,771,773,833,
893,782,742,860,849,850,812,945,775,784,746,1036,863,
750,763,871,817,749,838,986,794,867,758,923,804,733,
949,808,837,741,747,954,939,865,857,787,820,783,760,
911,745,928,818,887,847,978,852
) ORDER BY c.name ASC  

Мой первый проход по коду ужасно наивен, на одной странице около 10 таких запросов, и база данных не мигает.

Вы, конечно, могли бы запустить список значений в 100 КБ, что было бы совсем другой историей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...