Sql 当我选择。。。在“大数组”中?

Sql 当我选择。。。在“大数组”中?,sql,select,Sql,Select,比方说,我已经积累了一些id数组,例如[1,2,3,…,1000]。从数据库中选择这样大的数组是明智的。从数据库中取出10-20个东西的数组并不是什么大问题,但如果是1000-10000呢 编辑 不知何故,似乎,选择。。。在“选择…”中,从。。。0到100之间的速度要慢得多大约1200毫秒!!!,而不仅仅是形成一个数组并选择。。。在[array]中,通常,当需要基于ID数组选择1000多条记录时,比使用IN运算符更好的方法是将ID数组加载到临时表中,然后执行联接: 因此,与此相反: SELECT

比方说,我已经积累了一些id数组,例如[1,2,3,…,1000]。从数据库中选择这样大的数组是明智的。从数据库中取出10-20个东西的数组并不是什么大问题,但如果是1000-10000呢

编辑
不知何故,似乎,选择。。。在“选择…”中,从。。。0到100之间的速度要慢得多大约1200毫秒!!!,而不仅仅是形成一个数组并选择。。。在[array]

中,通常,当需要基于ID数组选择1000多条记录时,比使用IN运算符更好的方法是将ID数组加载到临时表中,然后执行联接:

因此,与此相反:

SELECT * FROM MyTable WHERE Id IN (...)
这样做:

CREATE TABLE #TempIDs ( Id AS INT );
-- Bulk load the #TempIDs table with the ID's (DON'T issue one INSERT statement per ID!)
SELECT * FROM MyTable INNER JOIN #TempIDs ON MyTable.Id = #TempIDs.Id
请注意评论。为了获得最佳性能,您需要一种机制来批量加载ID为的临时表-这取决于您的RDBMS和应用程序。

问题出在哪里 对解析器和优化器的压力 这类问题

SELECT * FROM x WHERE x.a IN (1,2,3,...,1000)
至少在Oracle中会转换为

SELECT * FROM x WHERE x.a=1 OR x.a=2 OR x.a=3 OR ... OR x.a=1000
您将得到一个非常大的解析器树,并且至少在Oracle中,您将达到解析器树的极限,拥有超过1000个值。因此,您对解析器和优化器施加了压力,这将损失一些性能。此外,数据库将无法使用某些优化

但还有另一个问题:

固定数量的绑定变量 由于您的查询使用OR表达式转换为等效查询,因此不能对IN子句SELECT*FROM x使用绑定变量,其中x.a IN:值将不起作用。只能对in子句中的每个值使用绑定变量。因此,当您更改值的数量时,将得到一个结构不同的查询。这会给查询缓存带来压力,至少在Oracle中会给游标缓存带来压力

解决 解决方案:使用范围
如果您可以描述您的查询,而无需对每个值进行编号,那么查询速度通常会快得多。例如,如果a.x>=1,而不是a.x在1,…,则1000写入a.x>=1和a.x,例如执行时间。会不会太大?执行什么的时间?选择。。。从…起在[…]查询中,在哪个数据库管理系统中?使用哪种表结构?id是主键还是什么?如果是的话,那么10k的PK读数是零,这很可能是MySQL。是的,id是表中的主键。但如果不是呢?同意,当您在操作中执行时,它只是对每个值进行ORing。如果在[…]中不是一个数组,而是子查询呢?那就更容易了,因为在这种情况下,您不需要批量加载任何内容。只需使用子查询进行内部连接即可。非常感谢。我会想办法的。谢谢你的回答,范围是不可能的,因为值不是常数。对于像我这样的新手来说,集合的解决方案仍然太复杂:所以我将尝试加入表。 DECLARE TYPE ILIST IS TABLE OF INTEGER; temp ILIST := ILIST(); result VARCHAR2(20); BEGIN temp.extend(3); temp(1) := 1; temp(2) := 2; temp(3) := 3; SELECT a.y INTO result FROM a WHERE a.x IN (select * from TABLE(temp)); END; /