私はしばらくの間、この問題について頭を悩ませていましたが、助けを求めることにしました。温度/湿度チャート レコーダー データ (現在 775,000 レコード以上) を保持するテーブルがあり、そこから統計クエリを実行しようとしています。問題は、これに 2 分ほどかかることが多く、まったく戻ってこないこともあり、プログラムを強制的に閉じなければならない (Control-Alt-Delete) ことです。最初はそれほど問題はありませんでした。500k レコードという魔法のマークに到達した後で初めて、深刻な速度低下が発生し始め、より多くのデータがコンパイルされてテーブルにインポートされるにつれて、次第に悪化しました。
クエリ (パススルー) は次のとおりです。
SELECT dbo.tblRecorderLogs.strAreaAssigned, Min(dbo.tblRecorderLogs.datDateRecorded) AS FirstRecorderDate, Max(dbo.tblRecorderLogs.datDateRecorded) AS LastRecordedDate,
Round(Avg(dbo.tblRecorderLogs.intTempCelsius),2) AS AverageTempC,
Round(Avg(dbo.tblRecorderLogs.intRHRecorded),2) AS AverageRH,
Count(dbo.tblRecorderLogs.strAreaAssigned) AS Records
FROM dbo.tblRecorderLogs
GROUP BY dbo.tblRecorderLogs.strAreaAssigned
ORDER BY dbo.tblRecorderLogs.strAreaAssigned;
チャート データが格納されるテーブル構造は次のとおりです。
idRecorderDataID Number Primary Key
datDateEntered Date/Time (indexed, duplicates OK)
datTimeEntered Date/Time
intTempCelcius Number
intDewPointCelcius Number
intWetBulbCelcius Number
intMixingGPP Number
intRHRecorded Number
strAssetRecorder Text (indexed, duplicates OK)
strAreaAssigned Text (indexed, duplicates OK)
開始日と終了日だけでなく、割り当てられたエリアに基づいてこのテーブルからデータを取得できるようにするプログラムを作成しようとしています。私が現在所有しているデータセットのサイズでは、この種のレポートは処理するには大きすぎて (どうやら)、マシンが回答を返すことはありません。このテーブルを処理するすべてのクエリで、ODBC タイムアウトをほぼ 180 秒に延長する必要がありましたが、これは単純にサイズの問題です。人々が何かを持っているなら、私はいくつかの深刻な助けを使うことができます. 前もって感謝します!
-- 2012 年 8 月 13 日 @ 1050 時間に編集 --
IT 部門が問題のマシンを制御し、誰かがリモート管理コンソールを使用してフルタイムでログインしているため、SQL Server でクエリをテストできませんでした。パフォーマンスの問題の影響を軽減するための暫定的な手順を試みましたが、この問題に対する恒久的な解決策を探しています。
中間ステップ:
dbo.tblRecorderLogs SQL Server テーブルの構造をミラーリングするローカル テーブルを作成しました。これに対して、以前の SELECT ステートメントをサブクエリとして使用して INSERT INTO を実行しました。その後の統計分析は、この「一時的な」ローカル テーブルから行われます。プロセスが完了すると、ローカル テーブルは切り捨てられます。
-- 2012 年 8 月 13 日 @ 1217 時間に編集 --
表示されているクエリを SQL Server 管理コンソールで実行しました。コンソールが提供するクエリ タイマーによると、完了までに 1 分 38 秒かかりました。
-- 2012 年 8 月 15 日 @ 1531 時間を編集 --
次のコードを使用して、VBA DoCmd.RunSQL ステートメントとしてクエリを実行し、一時テーブルにデータを入力しようとしました。
INSERT INTO tblTempRecorderDataStatsByArea ( strAreaAssigned, datFirstRecord,
datLastRecord, intAveTempC, intAveRH, intRecordCount )
SELECT dbo_tblRecorderLogs.strAreaAssigned, Min(dbo_tblRecorderLogs.datDateRecorded)
AS MinOfdatDateRecorded, Max(dbo_tblRecorderLogs.datDateRecorded) AS MaxOfdatDateRecorded,
Round(Avg(dbo_tblRecorderLogs.intTempCelsius),2) AS AveTempC,
Round(Avg(dbo_tblRecorderLogs.intRHRecorded),2) AS AveRHRecorded,
Count(dbo_tblRecorderLogs.strAreaAssigned) AS CountOfstrAreaAssigned FROM
dbo_tblRecorderLogs GROUP BY dbo_tblRecorderLogs.strAreaAssigned ORDER BY
dbo_tblRecorderLogs.strAreaAssigned
コードが実行されると問題が発生し、クエリに非常に時間がかかります.終了する前にタイムアウトが発生します. これを修正するための「魔法の弾丸」をまだ望んでいます...
-- 2012 年 8 月 20 日 @ 1241 時間に編集 --
私が見つけた唯一の「準」解決策は、失敗したクエリを繰り返し実行することです(いわば、ポンプをプライミングするようなものです)。これにより、クエリがプログラムによって再度呼び出されたときに、ODBC の前に実際に完了する可能性が相対的に高くなります。 SQL Server ドライバーがタイムアウトします。基本的に、不潔な不潔なハックですが、この問題に対処するためのより良いハックはありません。
- サーバー側で動作するビューを作成しようとしましたが、速度は上がりません。
- 集計されている適切なフィールドは適切にインデックス化されているため、そこを変更することはできません。
- 私は、データベースからユーザーにとってすぐに役立つ情報のみを引き出しています。ここでは「SELECT * madness」は行われていません。
私は、公式には、試してみることができないと思います-アイテムがライブではなく、より良いハードウェアを調達する予算がないため、問題に生のコンピューティング馬力を投入することは別として. これを「回答」として投稿し、9 月 3 日までそのままにしておきます。より良い回答がない場合は、自分の回答を受け入れて敗北を受け入れます。