【问题标题】:Query failed where runnig bigger time period (mssql server 2005 under php only)运行较大时间段时查询失败(仅限php下的sql server 2005)
【发布时间】:2014-06-21 17:56:08
【问题描述】:

我有一个奇怪的问题。

我正在运行一个查询:

SELECT IMIE, NAZWISKO, PESEL2, ADD_DATE, CONVERT(varchar, ADD_DATE, 121) AS XDATA, ID_ZLECENIA_XXX, * FROM XXX_KONWERSJE_HISTORIA AS EKH1
INNER JOIN XXX_DANE_PACJENTA EDP1 ON EKH1.ID_ZLECENIA_XXX=EDP1.ORDER_ID_XXX
WHERE EKH1.ID_KONWERSJE = (
    SELECT MIN(ID_KONWERSJE)
    FROM XXX_KONWERSJE_HISTORIA AS EKH2
    WHERE EKH1.ID_ZLECENIA_XXX = EKH2.ID_ZLECENIA_XXX
)
AND EDP1.RECNO = ( 
    SELECT MAX(RECNO) 
    FROM XXX_DANE_PACJENTA EDP2
    WHERE EDP2.ORDER_ID_XXX = EDP1.ORDER_ID_XXX
)
AND EKH1.ID_ZLECENIA_XXX LIKE '%140000393%'
AND ADD_DATE>'20140419' AND ADD_DATE<='20140621 23:59:59.999' 
ORDER BY EKH1.ID_KONWERSJE, EKH1.ID_ZLECENIA_XXX DESC 

如果我使用大约 2 个月(63 天 - 它给我 1015 个结果)的日期限制,则查询可以正常工作。如果我延长日期限制查询将失败(查询失败 blabla)。

这发生在 windows 64 位 php (apache, Xamp) 下。

当我直接从 MS SQL SERWER Management Studio 运行此查询时,一切正常,无论我选择什么日期限制。

发生了什么事?在 apache/php 下是否有某种限制? (没有“查询超时”之类的信息,只有“查询失败”)

【问题讨论】:

标签: php sql-server apache


【解决方案1】:

如果我使用大约 2 个月(63 天)的日期限制,查询工作正常 - 它给了我 1015 个结果)。如果我延长日期限制查询根本失败(查询失败blabla)。 ... 到底是怎么回事?有没有限制 某种在apache/php下? (没有“查询时间”之类的信息 超额”,只有“查询失败”)

这可能会发生,因为ADD_DATE&gt;'20140419' AND ADD_DATE&lt;='20140621 23:59:59.999' 的选择性中等/低(有[太多] 行满足此谓词)并且 SQL Server 必须多次扫描(是的,扫描)XXX_KONWERSJE_HISTORIA 以检查以下谓词:

WHERE EKH1.ID_KONWERSJE = (
    SELECT ...
    FROM XXX_KONWERSJE_HISTORIA AS EKH2
    WHERE EKH1.ID_ZLECENIA_XXX = EKH2.ID_ZLECENIA_XXX
)

必须扫描 SQL Server XXX_KONWERSJE_HISTORIA 表多少次才能验证此谓词?可以查看Table Scan [XXX_KONWERSJE_HISTORIA]数据访问算子的属性:3917次

一开始你可以做什么?您应该创建缺少的索引(请参阅执行计划上方带有绿色的警告):

USE [OptimedMain]
GO
CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[ERLAB_KONWERSJE_HISTORIA] ([ID_ZLECENIA_ERLAB])
INCLUDE ([ID_KONWERSJE])
GO

当我直接从 MS SQL SERWER Management Studio 运行此查询时 一切正常,无论我选择什么日期限制。

SQL Server Management Studio 的执行超时默认设置为 0(无执行超时)。

注意:如果此索引可以解决问题,那么您应该尝试 (1) 在 ADD_DATE 上创建一个包含所有必需 (CREATE INDEX ... INCLUDE(...)) 列的索引,以及 (2) 在这些表上创建唯一的聚集索引。

【讨论】:

  • 这是一个非常可靠的答案。谢谢你。我会检查一下,并创建适当的索引。还有一个计划 B - 我在数据库中创建了新表,我将在其中存储一些新数据,因此不需要这个复杂的查询。
【解决方案2】:

尝试通过ini_set在你的php脚本中设置这些php配置

ini_set('memory_limit', '512M');
ini_set('mssql.timeout', 60 * 20);

不确定它会帮助你。

【讨论】:

  • 设置 mssql.timeout 会更改通过 PHP 启动的任何给定 SQL 命令的执行限制(我认为默认值为 30 秒)。在 SMSS 中运行时,对 sql 命令没有限制。如果在托管环境中运行,由于管理限制,调用者可能无法实际更改此设置。
  • 通过 php 默认为 60 秒。是的,你是对的。
  • ini_set('memory_limit', '512M'); - 这是个好主意。我尝试了一次,脚本正在运行,并且正在运行,并且正在运行......直到我(从浏览器)获得有关连接限制的信息(服务器没有响应太久)。我会尝试用更小的内存限制做更多的测试。
  • 更多测试:通常增加内存限制是回馈“服务器没有响应太久”。也许这是我的 apache 错?或者可能是它的 mssql serwer 问题,因为我设法用这个查询阻止了它一次 - 在重新启动之前根本无法连接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-12
  • 1970-01-01
  • 2012-06-08
  • 1970-01-01
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
相关资源
最近更新 更多