にバグのステータス(など)を取得するための最良の(最速)の方法。現在、私は歴史のある日付のデータに基づいてレポートを作成するように変更しています。以前は、今日の状況からのデータしか表示していませんでした。のBugzilla、私はさまざまなソースからデータを取得し、レポートを生成するアプリケーションに取り組んでいる特定の日付
私のデータ源の1つは、Bugzillaのであるので、私は歴史の中で与えられた日付のBugzillaのデータを取得する必要があります。私はBugzillaデータベースへの読み取り専用接続を持っていますが、プラグインのインストールやデータベースへのプロシージャの挿入など、サーバーに何か他の操作を簡単に行う方法はありません。また、レポートサーバーとBugzillaのサーバー間の接続が遅いので、私は、サーバー上で計算を行うのではなく、レポートサーバー上のデータや作業物事をフェッチしたいと思います。
私は実際にこれは主に許容可能な速度で働いていますが、私はそれを最高のか、「正しい」やり方をやっているならば、私たちは追加として速度が許容されるのをやめるかもしれないという心配はよく分かりませんデータベースへのより多くの問題。
だから、私の解決策は以下の通りです - あなたはそれを行うだろうか。
バックグラウンドについては、Bugzillaはすべてのバグの現在の状態(「バグ」と呼ばれます)と、テーブル内の各フィールドの変更履歴(「bugs_activity」)を次のように表示します。
fieldid INTEGER, -- References the fielddefs table
bug_when TIMESTAMP, -- Time the change happend
added TEXT, -- New text for the field
removed TEXT, -- Old text for the field
BugzillaデータベースはMySQLです。私はそれを行う正しい方法は、ストアドプロシージャまたは一時テーブルのいずれかであると思うが、どちらのオプションも私には利用できません。私はBugzilla用のレポートツールもあると知っていますが、私はそれらをインストールするアクセス権がありません。また、私が生成しているレポートも他のソースからのデータを結びつけています(特定のフォーマットを持っています)。
レポートサーバにはローカルのPostgreSQLデータベースがありますので、すべてのデータを定期的にミラーリングすることができますが、実際には同じデータを2箇所に保存するのは少し無駄に思えます。
私の解決策は、通常のバグ表(特定のレポートに興味があるデータ)のようなサブセレクト内に表を作成し、この選択をソースとして使用して、今日のデータに基づくレポートのクエリと同じです。
SELECT bug_status, bug_id, op_sys, resolution, rep_platform
FROM (SELECT bug_id,
IFNULL((SELECT removed FROM bugs_activity a, fielddefs f
WHERE a.fieldid = f.id
AND bug_id = b.bug_id AND f.name = 'bug_status'
AND bug_when >= '2012-01-01 00:00:00'
ORDER BY bug_when DESC LIMIT 1), bug_status) AS bug_status,
-- Repeat IFNULL clause for op_sys, resolution and rep_platform
FROM bugs b
WHERE b.creation_ts <= '2012-01-01 00:00:00') bug_subselect
-- Some other filters to reduce the bugs (specific product, ect)
)
-- More filters based on the new values that have been derived
;
は、次に私が使用していることなどが異なるステータスをカウント選択への入力、など
このクエリは、それがために全体の結果を得ることですので、私はと仮定していますあまりにも遅いことが判明インナーはそれを注文し、私にトップを与えることができるように選択します。
bugs_activityテーブルをバグテーブルに数回ジョインしてから、その結果をIFNULLクエリで処理しましたが、これは高速でしたが、生成コードでは維持するのが少し複雑でしたので、
SELECT bug_status, bug_id, op_sys, resolution, rep_platform
FROM (SELECT bug_id,
IFNULL((SELECT removed FROM bugs_activity a, fielddefs f
WHERE a.fieldid = f.id AND bug_id = b.bug_id AND f.name = 'bug_status'
AND bug_when = (
SELECT MIN(bug_when) FROM bugs_activity a, fielddefs f
WHERE a.fieldid = f.id
AND bug_id = b.bug_id
AND f.name = 'bug_status'
AND bug_when >= '2012-01-01 00:00:00'
LIMIT 1
)
LIMIT 1), bug_status) AS bug_status,
-- Repeat IFNULL clause for op_sys, resolution and rep_platform
FROM bugs b
WHERE b.creation_ts <= '2012-01-01 00:00:00') bug_subselect
-- Some other filters to reduce the bugs (specific product, ect)
)
-- More filters based on the new values that have been derived
;
いくつかのフィールドは多分アップグレードから同じタイムスタンプ(のいずれかのデータベースグリッチ、上の2つの変更、または同じバグを編集する二人のユーザーを持っているために管理しているとして、あなたは(私が思う)そこに両方のLIMIT 1の者を必要とします - - 私は確信していない、私はそれがそこにあると私はそれに対処する必要があることを知っている)。
これは(最悪のケースであると起こることはほとんどないであろう)バグリストを減らすためにフィルタなしで約3秒で実行され、それはより速くフィルタを使用して実行されます。 LEFT JOINバージョンはほぼ同じスピード(わずかに遅い)で動作するので、上記のものと一緒に行きました。今のところ問題ありませんが、将来的には遅くなることがわかります。GUIに読み込みメッセージを追加します。これらのレポートの生成に時間がかかりそうだというメッセージが既に表示されています。それをより速くするためにいくつかのトリックがありません。
"私はそれをより速くするためにいくつかのトリックを欠けている場合、私はただ思ったんだけど" - うん。それらはインデックスと呼ばれています... –
bugs_activityテーブルにはインデックスがありません。 – SpaceDog
私は私が言ったことを正確に意味しました - インデックスはクエリをスピードアップします。 –