0

MySQL の質問です。

契約書と注文ファイルがあります。標準の親子 - 1 対多の関係。コントラクトには多くの注文を含めることができます。一般的な結合フィールドは c_contract_id = co_contract_id です。

契約には、契約を修飾する c_type_code があり、注文にも co_order_type_code があります。

ユーザーが多くのフィールドに基づいて選択できる一般的な検索を構築しています。問題を引き起こしているクエリは、contract または contract_orders テーブルのいずれかに特定の type_code を持つ契約の contract_id を見つけることです。

テーブルには、ユーザーが検索できる多くのフィールドがあります。私の質問に関連するフィールドは次のとおりです。

CREATE TABLE `ndx_contracts` (
  `c_contract_id` int(11) NOT NULL AUTO_INCREMENT,
  `c_type_code` char(2) NOT NULL,
  PRIMARY KEY (`c_contract_id`),
  KEY `c_type_code` (`c_type_code`)
) ENGINE=InnoDB AUTO_INCREMENT=1


CREATE TABLE `ndx_contract_orders` (
  `co_contract_id` int(11) NOT NULL,
  `co_contract_orderid` int(11) NOT NULL AUTO_INCREMENT,
  `co_order_type_code` varchar(2) NOT NULL,
  `co_data` varchar(255),
  PRIMARY KEY (`co_contract_orderid`,`co_contractid`),
  KEY `co_order_type_code` (`co_order_type_code`)
) ENGINE=InnoDB AUTO_INCREMENT=1


SELECT count(1)
FROM contracts
WHERE 
    c_type_code IN ('02')
        OR (
               (SELECT count(co_order_type_code) FROM contract_orders
                    WHERE
                        co_contract_id = c_contract_id
                        AND co_order_type_code IN ('02')
               ) > 0
           )
;    

このクエリは機能しますが、非常に遅いです。約 40,000 の契約しかなく、それぞれに約 4 つの注文レコードがあり、検索に 311 秒以上かかり、320 秒の行が返されます。

外部結合を行いますが、多くの余分な行が返されます。

ありがとうございました

4

1 に答える 1

1

個別のコントラクト ID を数えたいと思われるので、これで十分です。

SELECT COUNT(DISTINCT c.c_contract_id) AS `contract_id_count`
FROM ndx_contracts AS c
LEFT OUTER JOIN ndx_contract_orders AS co
  ON c.c_contract_id = co.co_contract_id
WHERE c.c_type_code = ? OR co.co_order_type_code = ?

これにより、注文のない契約の場合が可能になることに注意してください。は?明らかに、検索値が何であれ置き換えられます。実際の注文 ID 自体が必要な場合COUNT()は、select の関数を削除してください。

ただし、主キーのオンndx_contract_ordersは実際には問題です。この結合を行うには、contract_id のみでルックアップする場合、そのプライマリ インデックスのフィールドの順序を逆にして、contract_id のみによるインデックス付きルックアップを有効にする必要があります。または、 のインデックスを追加することもできますco_contract_id。正直なところ、注文IDが自動インクリメントの場合、そのフィールドだけが主キーになり、co_contract_idフィールドには独自のインデックスが必要です。order_id の主キーの自動インクリメントによって一意性が保証されるため、両方のフィールドで一意のインデックスを強制する必要はありません。

于 2013-04-09T20:25:07.707 に答える