2009-03-02 38 views
1

我有一个很奇怪的与SQL相关的问题。“无限”的sql语句?

我访问MSSQL Server 2005中使用PHP(ODBC),当我执行轨迹下面的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。 当我尝试在SQL Server Management Studio中执行该语句本身

SELECT fieldA, fieldB, fieldC, fieldD, fieldE FROM mytable WHERE fieldB IS NULL 

它工作正常(下1秒)。

任何想法?

编辑: 服务器之间的主要区别是,我的服务器是x86(Win2003),而客户的服务器是x64(Win2008)。

EDIT2:

+0

可以指定你和你的客户端是否有相同的数据集? – 2009-03-02 15:51:17

+0

不,它不是相同的数据集。我想知道为什么“原始”的声明是在两台机器上工作,但不是从php执行时... – chris 2009-03-02 15:56:43

回答

1

有没有WHERE在SELECT语句子句,所以你会做一个表扫描过的每一行都在该表中添加WHERE子句。如果你的客户有比你的本地服务器更多的行,这将解释时间差异。

+0

对不起,我截断了where子句。它只是“WHERE fieldB IS NULL” – chris 2009-03-02 15:59:16

0

您的光标被声明为DYNAMIC@p3 =2)。在Management Studio中,尝试将其声明为FAST FORWARD@p3=16),看看它是否有帮助。

粘贴您发布到Management Studio探查器输出,替换sp_cursorfecth参数:

exec sp_cursorfetch @p1, 2, 1, 1 

,看看问题是否仍然存在。

0

我不知道SQL服务器,但Oracle甚至没有索引NULL值。即使这样,字段IS NULL也不是选择性标准,因此您可能会得到全表扫描,如果您的客户拥有大量数据,则可能需要很长时间。

0

数据集越大需要的时间越长。你会想用一个where子句限制你的结果集。不要让你的应用服务器完成所有的工作。向要过滤的列添加索引将允许数据库服务器仅向您提供您想要的内容,以便以后不必循环。

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