Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用对列表高效地选择SQL server中的行?_Sql_Sql Server_Python 3.x_Pandas - Fatal编程技术网

使用对列表高效地选择SQL server中的行?

使用对列表高效地选择SQL server中的行?,sql,sql-server,python-3.x,pandas,Sql,Sql Server,Python 3.x,Pandas,我有一张相当大的桌子,有几百万行。我正在尝试编写一个高效的代码,该代码将选择在python代码中传递给它的成对列表中有两列值的行。一个合理的答案是 例如 返回的表通过pd.read\u sql\u query放入数据帧。我这里有两个问题(除了一个是速度慢)。其中,id2可以是NULL,并且对这些行的查询失败。另一个更重要的问题是,where子句中元组列表的大小可能变化很大,从1到数百万不等 我的理解是,在大列表情况下,最好使用pandas将整个列导入python,然后在那里进行过滤。但是,我如何

我有一张相当大的桌子,有几百万行。我正在尝试编写一个高效的代码,该代码将选择在python代码中传递给它的成对列表中有两列值的行。一个合理的答案是

例如

返回的表通过
pd.read\u sql\u query
放入数据帧。我这里有两个问题(除了一个是速度慢)。其中,
id2
可以是
NULL
,并且对这些行的查询失败。另一个更重要的问题是,
where
子句中元组列表的大小可能变化很大,从1到数百万不等


我的理解是,在大列表情况下,最好使用pandas将整个列导入python,然后在那里进行过滤。但是,我如何使小列表和大列表之间的转换平稳?有没有一种方法可以通过SQLServer和Python的巧妙结合来实现呢

where
子句

convert(id1) + '-' + id2 in ('2261-7807403')
这不是最优的。我们可以很容易地看到,这里我们期望
id1
为2261,
id2
为7807403,因此最好使用where子句,如

where (id = '2261' and id2 = '7807403')
您可以执行类似于(…)或(…)或(…)等的
where
子句。如果要允许
id2
值为
null
,可以

where (id = '2261' and isnull(id2, '7807403') = '7807403')

如果仍然存在性能问题,那么您可以考虑对这些列进行索引。


现在,我们还必须讨论一个迄今尚未解决的问题,即规模。你需要定义在你的案例中什么是大的。如果元素的数量很大,则将查询转换为CSV文件(或多个文件,如果需要)并使用Python加载。因此,为了避免在不合适的情况下加载大数据,您可以先选择count(*)并确定它是否大。

您应该使用正确的类型传递值。一种方法是构造派生表并使用
join

select t.*
from table t join
     (values (2261, 7807403), . . . 
     ) v(id1, id2)
     on t1.id1 = v.id1 and t.id2 = v.id2;
不应将值转换为字符串进行比较。这不仅是“荒谬的”,而且会严重影响绩效

对于
NULL
s,除非您有特殊的逻辑,否则它们将不匹配。SQL没有空安全比较

select t.*
from table t join
     (values (2261, 7807403), . . . 
     ) v(id1, id2)
     on (t1.id1 = v.id1 or t1.id1 is null and t2.id2 is null) and 
        (t.id2 = v.id2 or t1.id1 is null and t2.id2 is null);

请注意,这可能会影响执行计划。

元素的数量可以在100万到100万之间变化。@guy12345您可以创建一个临时表。当值的数量很小时,我运行此查询没有任何问题,但当值的数量超过100时,它就会被卡住。有什么解决办法吗?我们是否需要为
v
表编制索引?@guy12345。
t1(id2,id2)
上的索引将用于第一个查询。优化第二个更为棘手。我们如何设置该索引?为什么更棘手<代码>空不允许用于复合索引?@guy12345。SQL Server可能不会将索引用于支持
NULL
所需的更复杂的比较。索引明确支持
NULL
s;这不是问题所在。SQL Server没有
NULL
-安全的比较运算符,不善于优化
s。
select t.*
from table t join
     (values (2261, 7807403), . . . 
     ) v(id1, id2)
     on (t1.id1 = v.id1 or t1.id1 is null and t2.id2 is null) and 
        (t.id2 = v.id2 or t1.id1 is null and t2.id2 is null);