大IN()句を使用してMySQLのクエリの最適化や派生テーブルに参加します
-
21-09-2019 - |
質問
私は会社の仲間を照会する必要がありましょうと言います。私は、作られたすべてのトランザクションに関するデータが含まれている「取引」を、テーブルを持っています。
CREATE TABLE `transactions` (
`transactionID` int(11) unsigned NOT NULL,
`orderID` int(11) unsigned NOT NULL,
`customerID` int(11) unsigned NOT NULL,
`employeeID` int(11) unsigned NOT NULL,
`corporationID` int(11) unsigned NOT NULL,
PRIMARY KEY (`transactionID`),
KEY `orderID` (`orderID`),
KEY `customerID` (`customerID`),
KEY `employeeID` (`employeeID`),
KEY `corporationID` (`corporationID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
これは、仲間のために、このテーブルを照会するためにかなり簡単だが、ねじれがあります:トランザクション・レコードは、従業員ごとに一度登録されており、そのためにつき1つの企業のための複数のレコードがあるかもしれません。
。 会社1から従業員AとBの両方法人2に真空掃除機の販売に関与していた場合は、は、例えば、「取引」テーブル内の2つのレコードが存在することになります。各従業員に1つ、両方これはものの、結果に影響を与えてはならない企業1.。企業1からの貿易は、関係なく、関与していたどのように多くの従業員のの、1として扱われる必要があります。
簡単に、私は思いました。
:私はそうのように、派生テーブルに参加しますよSELECT corporationID FROM transactions JOIN (SELECT DISTINCT orderID FROM transactions WHERE corporationID = 1) AS foo USING (orderID)
クエリは、私が必要とするまさにコーポレーション1との取引に関与してきた企業のリストを返しますが、MySQLが派生テーブルを決定するためにcorporationIDインデックスを使用することはできませんので、それは非常に遅いです。私はこれがすべてのサブクエリ/ MySQLで派生テーブル用のケースがあることを理解します。
私はまた別途のOrderIDsのコレクションを照会し、途方もなく大きなIN()句(typhically 100 000+ ID)を使用しようとしたが、MySQLのように途方もなく大きなIN()句にインデックスを使用して問題を持っているからそれが変わるとうまくその結果、クエリ時間は向上しません。
他のオプションが利用可能である、または私はそれらの両方を使い果たしてしまった?
解決
私はあなたの条件を理解していれば、あなたはこれを試すことができます。
select distinct t1.corporationID
from transactions t1
where exists (
select 1
from transactions t2
where t2.corporationID = 1
and t2.orderID = t1.orderID)
and t1.corporationID != 1;
またはこの:
select distinct t1.corporationID
from transactions t1
join transactions t2
on t2.orderID = t1.orderID
and t1.transactionID != t2.transactionID
where t2.corporationID = 1
and t1.corporationID != 1;
他のヒント
あなたのデータは、私には意味がありません、私はあなたのクエリがcorporationIDsを取得するためのorderIDに基づいてcorporationID = 1のトランザクション表にトランザクションテーブルをジョインとしてあなたは、そこの中でいくつかの点でどこ平均顧客ID corporationIDを使用していると思います...これは、その後1でしょうね?
あなたは顧客IDは、社員コード、およびcorporationIDsが何を意味するかを指定していただけますか?どのように私は、従業員AとBは、企業1からのものを知っています - ?その場合には、corporationID企業1で、企業2は、顧客である、そしてその得意先に保存されている。
その場合は、あなただけでグループを実行する必要があります:
SELECT customerID
FROM transactions
WHERE corporationID = 1
GROUP BY customerID
(ご注文ごとに1つの行をしたい場合は代わりに、顧客ごとに1行ののorderIDするか選択し、グループ。)
でグループを使用することで、社員コードを除いて、重複している複数のレコードがあるという事実を無視します。
逆に、戻りの企業2に販売しているすべての企業ます。
SELECT corporationID
FROM transactions
WHERE customerID = 2
GROUP BY corporationID