私はフォームのテーブルを持っています
CREATE TABLE data
{
pk INT PRIMARY KEY AUTO_INCREMENT,
dt BLOB
};
約 160,000 行あり、blob 列には約 2GB のデータがあります (blob あたり平均 14kb)。別のテーブルには、このテーブルへの外部キーがあります。
3000 くらいのブロブが同一です。だから私が欲しいのは、重複を削除できる再マップテーブルを提供するクエリです。
単純なアプローチでは、30 ~ 40k 行で約 1 時間かかりました。
SELECT a.pk, MIN(b.pk)
FROM data AS a
JOIN data AS b
ON a.dt=b.dt
WHERE b.pk < a.pk
GROUP BY a.pk;
他の理由で、ブロブのサイズを含むテーブルをたまたま持っています。
CREATE TABLE sizes
(
fk INT, // note: non-unique
sz INT
// other cols
);
fk と sz の両方のインデックスを作成することで、50k 行で約 24 秒かかるダイレクト クエリが実行されます。
SELECT da.pk,MIN(db.pk)
FROM data AS da
JOIN data AS db
JOIN sizes AS sa
JOIN sizes AS sb
ON
sa.size=sb.size
AND da.pk=sa.fk
AND db.pk=sb.fk
WHERE
sb.fk<sa.fk
AND da.dt=db.dt
GROUP BY da.pk;
ただし、これは da (データ テーブル) に対して完全なテーブル スキャンを実行しています。ヒット率がかなり低くなければならないことを考えると、インデックス スキャンの方が優れていると思います。それを念頭に置いて、データの 3 番目のコピーを 5 番目の結合として追加し、約 3 秒を失いました。
質問はOKです:私は2番目の選択よりもはるかに良くなるでしょうか?もしそうなら、どのように?
少しの結果は次のとおりです。キー列が非常に頻繁に使用されるが、残りはめったに使用されないテーブルがある場合、そのテーブルの別の結合を追加して、インデックススキャンとフルスキャンを促進する方が良いでしょうか?テーブルスキャン?
#mysql@irc.freenode.net の Xgc は、サイズのようなユーティリティ テーブルを追加し、一意の制約をオンにすると非常にfk
役立つ可能性があると指摘しています。トリガーのいくつかの楽しみとそうでないものは、最新の状態に保つのに悪くないかもしれません.