1

ここで2つのかなり大きなテーブルにクエリを実行して、いくつかの結果を取得しようとしていますが、効率に問題があります。

注:これをそれほど乱雑に見せないように、関連する列のみを含めました。

TableA(在庫)には、productID、ownerID、およびcount列があります

TableB(所有者)には、ID、accountHolderID、および名前の列があります

私がやろうとしているのは、TableAにクエリを実行することです。ここで、productID = Xは、Stock.productID、Stock.accountHolderID、およびOwners.nameをプルアップします。これら2つのテーブル間の関係はStock.ownerID=Owners.IDであるため、WHERE条件が5つのproductIDを取得した場合、TableAのownerIDと一致するTableBの名前が必要になります。

この状況での唯一の一意のIDは、TableBのOwners.IDです。

これらの製品に対してTableAで基本的なSELECTクエリを実行するだけで15秒かかりますが、TableBに一致するようにINNER JOINを追加すると、クエリにかかる時間が大幅に長くなり、10分以上かかります。このクエリを非効率的に設計したと思います。

SELECT
Owners.name,
Stock.productID,
Stock.ownerID
FROM Stock
INNER JOIN 
Owners
ON Stock.ownerID = Owners.ID
WHERE
Stock.productID = 42301679

このクエリをより効率的にするにはどうすればよいですか?

WHERE条件にORを追加すると、一度に複数のproductIDを取得できますか?

4

3 に答える 3

1

あなたのクエリは正しいように見えます。おそらくスキーマを確認できます

複数の productID を一度に取得するには、IN代わりに演算子を使用できます。OR

SELECT
Owners.name,
Stock.productID,
Stock.ownerID
FROM Stock
INNER JOIN 
Owners
ON Stock.ownerID = Owners.ID
WHERE
Stock.productID IN (42301679,123232,232324)
于 2012-10-16T01:20:40.853 に答える
1

productID が Stock テーブルで一意である場合、これをインデックスにすることは理にかなっており、他の人が述べたように、これによりパフォーマンスが大幅に向上します。

もう 1 つのパフォーマンスの向上は、特定の長さの Owner.name フィールドを設定することによって得られます。mySQL では、可変長の文字列に VARCHAR を使用できますが、CHAR(32) 列は名前が常に 32 文字を占めることを示します。余分な未使用スペースはパディングされるだけなので、(32) は最大長を示していると考えることができます。パフォーマンスの利点は、データベースが各行が占有するバイト数を正確に認識し、この情報を使用してルックアップ時間を改善できるという事実から得られます。

于 2012-10-16T02:10:57.120 に答える
1

あなたのコメントによると、owners.id フィールドの非常に重要なインデックスが欠落しているようです。ここで、このインデックスはこのクエリに役立つことに注意してください。ただし、このテーブルに対して実行される他のすべてのクエリを考慮して、そのインデックスを追加することが適切かどうかを判断する必要があります。

29M 行の場合、頻繁に挿入されるテーブルにインデックスがあると、挿入時間に顕著な影響を与える可能性があります。

これは、さまざまなアプリケーションがさまざまなインデックスを必要とする状況である可能性があります。つまり、OLTP アプリとレポート アプリ (アドホック クエリを実行しているだけかもしれません)。一般的な解決策は、この機能に合わせて適切に調整されたインデックスを持つレポート/データ ウェアハウス クエリを実行する 2 台目のサーバーを用意することです。

幸運を祈ります。

于 2012-10-16T01:45:33.577 に答える