1

これが私の設定です:

テーブルrecordsには、他のいくつかの列とともに複数(2つ以上)のPKID列が含まれています。

テーブルcached_recordsには2つの列しかありません。これは、の2つのPKIDと同じですrecords

たとえば、recordsPKIDが「keyA」、「keyB」、および「keyC」であり、「keyA」と「keyB」cached_recordsのみがあると仮定します。

records適切なPKID(つまり、「keyA」と「keyB」)がテーブルにないテーブルから行をプルする必要がありcached_recordsます。

PKIDを1つだけ使用していた場合、このタスクがどれほど簡単になるかを知っています。

SELECT
    pkid
FROM
    records
WHERE
    pkid NOT IN (SELECT pkid FROM cached_records)

ただし、PKIDが2つあるということは、単純なを使用できないことを意味しNOT INます。これは私が現在持っているものです:

SELECT
    `keys`.`keyA` AS `keyA`,
    `keys`.`keyB` AS `keyB`
FROM
    (
        SELECT DISTINCT
            `keyA`,
            `keyB`
        FROM
            `records`
    ) AS `keys`
        LEFT JOIN
                `cached_records` AS `cached`
            ON
                    `keys`.`keyA` = `cached`.`keyA`
                AND
                    `keys`.`keyB` = `cached`.`keyB`
WHERE
    (
            `cached`.`keyA` IS NULL
        AND
            `cached`.`keyB` IS NULL
    )

(テーブルDISTINCTから複数のPKIDのうち2つしか取得してrecordsいないため、重複する可能性があり、実際には重複する必要がないため、これが必要です。「keyC」は使用されておらず、レコードの一意性を判断するのに役立ちます)。

上記のこのクエリは問題なく機能しますが、cached_recordsテーブルが大きくなるにつれて、クエリの処理にかかる時間が長くなります(ここで数分話しているのですが、コードがハングしてクラッシュするのに十分な時間がかかる場合があります)。

したがって、この種の操作(行が別のテーブルに存在しないテーブルから行を選択する)を1つではなく複数のPKIDSで実行するのが最も効率的な方法は何でしょうか...

4

1 に答える 1

2

これはもっと速いはずです:

SELECT  DISTINCT
    `records`.`keyA` AS `keyA`,
    `records`.`keyB` AS `keyB`
FROM
    `records`
        LEFT JOIN
                `cached_records` AS `cached`
            ON
                    `records`.`keyA` = `cached`.`keyA`
                AND
                    `records`.`keyB` = `cached`.`keyB`
WHERE
            `cached`.`keyA` IS NULL -- one is enough here

ノート:

  • クエリをテーブルとして使用すると、パフォーマンスが大幅に低下します。ここで最も外側のSELECTで区別を行うことができます。
  • 2つのキーのいずれかがヌルであるかどうかを確認するだけで十分です。これは、いずれもヌルになる可能性がないためです。
  • と列が同じタイプであり、変換が発生しないことを確認する必要がkeyAあります(実際のコードの動作でそのように見られます...)keyB
  • テーブルに適切なインデックスが必要です。このクエリの分は、何かひどいことが起こっている兆候です...(または非常に大量のデータ)
于 2012-10-21T21:23:39.493 に答える