ある企業の関係者に問い合わせる必要があるとしましょう。行われたすべてのトランザクションに関するデータを含む「トランザクション」テーブルがあります。
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 つの企業に対して複数のレコードが存在する場合があります。
たとえば、企業 1 の従業員 A と B の両方が企業 2 への掃除機の販売に関与していた場合、"transactions" テーブルには 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 のすべてのサブクエリ/派生テーブルに当てはまることを理解しています。
また、orderID のコレクションを個別にクエリし、途方もなく大きな IN() 句 (通常は 100 000 以上の ID) を使用しようとしましたが、MySQL には、途方もなく大きな IN() 句でインデックスを使用する際にも問題があることが判明しました。その結果、クエリ時間は改善されません。
他に利用可能なオプションはありますか、それとも両方とも使い果たしましたか?