0

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

クエリのサイズ (最適化されていないと呼びます) を見るとわかるように、患者、医師、受けたサービス、何時、どの会社から来たかを示しています。そのため、しばらくは役に立ちましたが、再び速度が遅くなったインデックスを作成しました。localhost でシステムを実行すると、ライブ システムで結果が表示されるまでに約 15 秒かかり、タイムアウトします。

速度を改善する方法と、それらを正確に実装する方法を提案できますか。

参考までに、各テーブルの行は次のとおりです。

  • 患者アプリの詳細 - 195k
  • 患者 - 34,000
  • スタッフ - 200
  • 部門サービス - 700
  • インプロバイダー - 2800

ありがとうございました

4

2 に答える 2

1

一般に、多くの結合がある場合、特に多くのレコードを少数に結合する場合 (医師/スタッフの詳細への患者の予約など)、これらのレコードを個別に取得して SQL サーバーの外部で結合することは理にかなっています -アプリケーションサーバー上。
医師/スタッフ/部門サービス (およびおそらく insproviders) の詳細を一度取得し、アプリケーション サーバーのアプリケーション キャッシュに保存することをお勧めします。次に、SQL クエリは患者と予約の詳細を取得するだけで済み、結果セットはかなり小さくなります (レコードが短くなります)。
また、選択したサイズ (ある種のレポート機能だと思います) を考慮して、ここでページングやバッチ処理を検討する必要があります。

于 2012-09-17T14:05:44.930 に答える
1

さて、インデックスから始めましょう。patienappointments.date のインデックスを作成したと仮定します。これはクラスター化された種類のものです。また、ds.departgroupid にインデックスがあると仮定します。いくつかのテーブルのサイズが不足していますが、それらの左結合が原因であると推測します。クエリの実行計画は、いくつかの興味深い結果をもたらすはずです (ここに投稿できれば、いくつかの疑問を払拭するのに役立つかもしれません)。日付フィールドにインデックスがない場合は、シーケンシャル テーブル スキャン (テーブル全体の読み取り) に直面しており、これは非常に悪いことです。それらの 1 つがクエリ プランを台無しにしている可能性があるため、これらの左結合も確認してください。

経験則として、私はこれを行います:

  1. 内部結合のみでクエリを実行し、所要時間をテストします
  2. そのためのクエリ プランを取得し、最適化できるかどうかを確認します (主にインデックスを追加することにより)。
  3. ステップ 1 のクエリを WHERE ステートメントで実行します。
  4. クエリ プランと最適化
  5. 左結合を 1 つずつ追加します
  6. クエリ プランと最適化

などなど…

それでも、クエリに多くの時間がかかる場合があります。その場合、できることが 2 つあります。

  1. ハードウェアを追加します (より多くのメモリとより優れたディスクを使用しても問題はありません)。
  2. 最適化の入力に基づいて、オプティマイザーが適切な部分を高速化できるように、テンポラル テーブルを使用してクエリを小さな部分に分割します。
于 2012-09-17T14:07:12.400 に答える