2つの異なるテーブルの都市を一致させる必要があります。どちらにも、郵便番号と名前があります。しかし、たとえば、1つの「BOURGES」と「18000」ともう1つの「BOURGESCEDEX」と「18006」があります。
私はこれを初めて試しました:
INNER JOIN b_agence ag ON ag.ville = c.li_commune AND ag.code_postal = c.cd_postal
私はそれをに変更しました:
INNER JOIN b_agence a ON (trim(c.li_commune) = trim(replace(a.VILLE,'CEDEX','')) AND left(a.CODE_POSTAL,2) = left(c.cd_postal,2) )
それは機能しますが、残念ながら私の要求は30秒以上かかります。どうすれば最速の方法でそれを達成できますか?
問題は、TRIMを導入することにより、クエリを実行するたびにSQLエンジンに全表スキャン(文字列操作も含む)を強制することです。高速にしたい場合は、VILLE_TRIMMEDなどの新しいフィールドを作成し、「CEDEX」を削除した値を一度に入力します(値が追加または変更されている場合は、値を最新の状態に保つためのトリガーを導入する必要がある場合があります) )、その新しいVILLE_TRIMMEDフィールドにインデックスを付け(そして、ソースli_communeフィールドにもインデックスが付けられ、両方のテーブルの郵便番号フィールドにもインデックスが付けられていることを確認します)、それに結合します。そうすれば、クエリは毎回全表スキャンを実行するのではなく、インデックスを使用して結合を実行できるため、桁違いに高速になります。
ここで非正規化を導入していることに気付くでしょう。これは一般的なパターンです。データを整理するために正規化します。速度を非正規化します。
データベースがSQLServerの場合、計算列としてVILLE_TRIMMEDを実行し(最後から「CEDEX」のトリミングを実行)、PERSISTEDとしてマークしてから、それに参加することができます。トリガーなどの手間を省き、列を最新の状態に保ちます。SQLServerエンジンがそれを処理します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加