我有一个非常奇怪的与sql相关的问题。
我正在使用PHP(odbc)访问MSSQL Server 2005,当我对sql语句进行概要分析时执行以下操作:
declare @p1 int
set @p1=180150003
declare @p3 int
set @p3=2
declare @p4 int
set @p4=1
declare @p5 int
set @p5=-1
exec sp_cursoropen @p1 output,N'SELECT fieldA, fieldB, fieldC, fieldD, fieldE FROM mytable WHERE fieldB IS NULL',@p3 output,@p4 output,@p5 output
select @p1, @p3, @p4, @p5
exec sp_cursorfetch 180150003,2,1,1
在我自己的服务器上运行正常,在客户服务器上sp_cursorfetch读取无限行并加载完整的cpu。 当我尝试执行语句本身时
SELECT fieldA, fieldB, fieldC, fieldD, fieldE FROM mytable WHERE fieldB IS NULL
在SQL Server Management Studio中工作正常(1秒内)。
有什么想法吗?
编辑: 服务器之间的主要区别是我的服务器是x86(Win2003),客户的服务器是x64(Win2008)。
Edit2:添加了Where-Clause
答案 0 :(得分:1)
该SELECT语句中没有WHERE子句,因此您将对该表中的每一行进行表扫描。如果您的客户的行数多于本地服务器,则可以解释时间差异。
答案 1 :(得分:0)
您的光标被声明为DYNAMIC
(@p3 =2
)。在Management Studio
中,尝试将其声明为FAST FORWARD
(@p3=16
)并查看是否有帮助。
将您发布的探查器输出粘贴到Management Studio
,替换sp_cursorfecth
中的参数:
exec sp_cursorfetch @p1, 2, 1, 1
并查看问题是否仍然存在。
答案 2 :(得分:0)
我不知道SQL服务器,但Oracle甚至没有索引NULL值。即使它确实如此,字段IS NULL也不是一个选择性标准,因此您可能会获得全表扫描,如果您的客户拥有大量数据,这可能需要很长时间。
答案 3 :(得分:0)
数据集越大,所需的时间越长。您将希望使用where子句限制结果集。不要让您的应用程序服务器完成所有工作。向要过滤的列添加索引将允许数据库服务器仅提供您想要的内容,因此您不必在以后循环它。
答案 4 :(得分:0)
好吧,我不确定(我的公司)是否允许我在这里填写完整的sql语句。
这就是我在PHP中实际执行的内容:
SELECT
A.id, A.empl, A.valid_from,
A.salutation, A.account
FROM persons A
LEFT JOIN persons_comp B
ON
A.id = B.id
AND A.empl = B.empl
AND A.valid_from = B.valid_from
AND A.salutation = B.salutation
AND A.account = B.account
WHERE
B.empl IS NULL