私がサポートしているレガシー製品では、mysql への PHP クエリが動作する場合とハングする場合があります (おそらく有限ですが、そうであれば不当に長い時間です)。私の SQL スキルはかなり限られていますが、mysql で手動でクエリを実行できました。これまでにわかったことは次のとおりです。
テーブル「orders」、「lineItems」、および「lineItemDefns」が与えられた場合、
各オーダーは 1 対多の lineItem であり、lineItem は lineItemDefinitions と 1 対 1 です
各レポート (reportId) を注文のグループとその lineItem データ、および次の SQl クエリにマップするテーブル OrderReports:
SELECT SEC_TO_TIME(SUM(orders.itemCount*lineItems.itemCount*lineItemDefns.estimatedDuration)) as estimatedTotalDuration
FROM orders, lineItems, lineItemDefns
WHERE orders.id=lineItems.parentOrder
AND lineItemDefns.id=lineItems.definitionId
AND orders.id in
(SELECT DISTINCT orderId
FROM OrderReports
WHERE OrderReports.reportId=98619);
(これは、PHP で DBI getAll を呼び出す直前にクエリ文字列からダンプされたものです。)
2番目の選択を単独で実行すると、ほぼ瞬時に単一の行が返されます。その orderId を 2 番目の選択に置き換えて最初の選択を実行すると、1 秒以内に NULL の EstimatedTotalDuration が返されます。この reportId には 2 つの行しかありません。これは、この注文の 2 つの lineItem 行に対応しています。lineItems (lineItemDefns 内) の EstimatedDurations は両方とも NULL です。
クエリ内のプライマリ ID と外部 ID のすべての ID がインデックス化されます。
すべての数値は整数で、継続時間は秒単位です (int(11))。この場合の itemCounts は 1 です。
しかし、上記のように実行すると、テストデータベースで動作します (30 秒で遅くなります) が、本番データに関する同等のレポートのために不当な時間 (50 分以上) 放置すると完了しません。
レポートがハングしている間に最初の 2 つの部分的なクエリ テストを実行できるため、テーブルがロックされているようには見えません。
誰かが明らかな原因を指摘できますか (たとえば、null EstimatedDurations を処理しますか?)。同様に、次に何を見るべきかについてのヒントはありますか? これは本番データベースなので、他のユーザーに遅延を引き起こす可能性のあることはしたくありません。
クエリを書き直すための提案もいただければ幸いです。
Fedora 7 の mysql 5.0.37 (テスト データベースは Fedora 8 の mysql 5.0.45 です)
ビッグバン セオリーのペニーのように、私が知っているのはそれだけです。ああ、フィグ ニュートンはマサチューセッツ州ニュートンにちなんで名付けられました。;)