大型 SQL Server 数据库超时 PHP Web 应用程序

Posted

技术标签:

【中文标题】大型 SQL Server 数据库超时 PHP Web 应用程序【英文标题】:Large SQL Server database timing out PHP web application 【发布时间】:2012-09-09 17:57:58 【问题描述】:

我们正在运行一个使用 php 创建的基于 Web 的医院系统。由于数据库较小,系统最初速度很快,但现在变得很慢。

以下是查询示例

select pa.id, pa.date as date, pa.visitno, pa.receiptno, pa.debitnoteno, pad.id as padid,
 pad.serviceid as serviceid, pad.waitno, pa.paytype, s.id as doctorid, s.fullname as
 doctorname, p.id as patientid, p.name as patient, p.regno, p.age, p.gender, p.doc,
 p.department, p.telno, p.address, pa.ins_prov_id, ip.name as provider,
 pa.sicksheet_billcode as billcode, ds.id as serviceid, ds.name as servicename, ds.departid
 as departid, ds.servicetype as servicetype, pad.charge, pad.status as status, ts.id as
 timeslotid, ts.name as timeslot, pad.treatment, sd.anesthesiologist, sd.hospitalcharge,
 sd.anesthcharge from patientappointments as pa
INNER JOIN patientappdetails as pad ON pa.id = pad.patappid 
INNER JOIN patients as p ON pa.patid = p.id 
INNER JOIN staffs as s ON pad.doctorid = s.id 
LEFT JOIN departmentalservices as ds ON pad.serviceid = ds.id 
LEFT JOIN insproviders as ip ON pa.ins_prov_id = ip.id 
LEFT JOIN timeslots as ts ON pad.timeslotid = ts.id 
LEFT JOIN surgerydetails as sd ON sd.appdetid = pad.id 
where 1 = 1 and pa.date >= '01.Jul.2012' and ds.departgroupid = 16 and pad.charge != 0

您可以看到我们查询的大小(称为未优化),其中显示了患者、医生、所接受的服务、他来自什么时间和哪个公司。所以现在我们创建了在一段时间内确实有帮助的索引,但现在速度又变慢了。在本地主机上运行系统大约需要 15 秒才能在实时系统上显示结果,超时

您能否提出任何提高速度的方法以及具体实施方法。

仅供参考,每个表中的行如下:

患者应用程序详细信息 - 195k 患者 - 34k 员工 - 200 部门服务 - 700 insproviders - 2800

谢谢

【问题讨论】:

【参考方案1】:

通常在您有很多联接的情况下,尤其是在将大量记录联接到少数记录时(每个患者的预约到医生/员工的详细信息等),单独获取这些记录并将它们加入外部是有意义的SQL 服务器 - 在应用程序服务器上。 我建议一次获取医生/员工/部门服务(可能还有 insproviders)的详细信息,并将它们存储在应用程序服务器上的应用程序缓存中。然后,您的 SQL 查询将只需要获取患者和预约的详细信息,这将导致结果集相当小(更短的记录)。 考虑到您选择的大小(我假设它是某种报告功能),您应该在这里考虑分页和/或批处理。

【讨论】:

【参考方案2】:

好吧,让我们从索引开始。 我假设您已经为 patienappointments.date 创建了一个索引,它属于集群类型。我还假设您在 ds.departgroupid 上有一个索引。 你错过了几个表的大小,但我猜那些左连接是罪魁祸首。 查询执行计划应该会产生一些有趣的结果(如果你可以在这里发布它可能有助于消除一些疑问)。如果您在日期字段上没有索引,那么您将面临顺序表扫描(读取整个表),这真的很糟糕。还要检查那些左连接,因为其中一个可能会弄乱查询计划。

根据经验,我会这样做:

    仅使用内部联接运行查询,并测试所需时间 为此获取查询计划,看看是否可以优化(主要通过添加索引) 使用 WHERE 语句运行步骤 1 的查询 查询计划和优化 一次添加一个左连接 查询计划和优化

等等……

即便如此,您的查询最终可能会花费大量时间,在这种情况下,您可以做两件事

    添加更多硬件(拥有更多内存和更好的磁盘永远不会有坏处) 根据优化的输入,使用时态表将查询拆分为更小的部分,优化器可以加速好的部分。

【讨论】:

奇怪的解决方案感谢您建议的优化。当我将 8 月 5 日作为起始日期时,它在 1 秒内完成,而从 8 月 20 日开始需要一分钟多的时间。一开始很奇怪,所以我重新创建了索引,现在两个查询都在 1 秒内运行。索引是否损坏?

以上是关于大型 SQL Server 数据库超时 PHP Web 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

是否记录 SQL Server 超时?

SQL Server 的超时设置

导入大型数据库 - CPanel & MySQL & PHPMyAdmin

[Microsoft][ODBC SQL Server Driver]超时已过期

无法从 Sql Server 2005 获取数据(连接超时异常)

在 SQL Server 中强制查询超时