【发布时间】:2009-01-17 05:12:44
【问题描述】:
当 IN 或 NOT IN 的条件非常大时,我的应用程序出现内存不足异常。我想知道这样做的限制是什么。
【问题讨论】:
标签: mysql
当 IN 或 NOT IN 的条件非常大时,我的应用程序出现内存不足异常。我想知道这样做的限制是什么。
【问题讨论】:
标签: mysql
我遇到了类似的问题,但在我的 IN 子句中只传递了 100 个 3 位 id。当我查看堆栈跟踪时,它实际上切断了 IN 子句中的逗号分隔值。我没有收到错误,我只是没有得到所有结果返回。以前有没有人遇到过这样的问题?如果它相关,我正在使用 symfony 框架......我正在检查它是否是一个推进问题,但只是想要看看会不会是sql
【讨论】:
也许您最好用另一种方式来完成您的查询?
我建议您将匹配值加载到单列表中,然后将正在查询的列内连接到新表中的单列。
而不是
SELECT a, b, c FROM t1 WHERE d in (d1, d2, d3, d4, ...)
建立一个有 1 列的临时表,称之为“dval”
dval ---- d1 d2 d3SELECT a, b, c FROM t1
INNER JOIN temptbl ON t1.d = temptbl.dval
【讨论】:
我只在条件非常小时(不到 100 行左右)时才使用 IN 和 NOT IN。它在这些场景中表现良好。当条件很大时,我使用 OUTER JOIN,因为查询不必为每个元组查找“IN”条件。您只需检查您希望所有行来自的表。
对于“IN”,连接条件不为空
对于“NOT 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 */
【讨论】:
在执行 SQL 查询或数据库设计时必须询问限制是您做错了的一个很好的指标。
【讨论】:
我使用了包含大量 ID 列表的 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 个这样的查询,并且数据库不会闪烁。
当然,您可以运行一个包含 100k 值的列表,这完全是另一回事。
【讨论】:
我不知道限制是什么,但我以前也遇到过这个问题。我不得不像这样重写我的查询:
select * from foo
where id in (select distinct foo_id from bar where ...)
【讨论】: