2013-04-09 10 views
0

MySQL的問題。Mysql測試兩個表中的任何一個是父母和子女的值

我有合同和訂單文件。一個標準的父母和孩子 - 一對多的關係。 合同可以有很多訂單。公共連接字段是c_contract_id = co_contract_id。

合同有一個c_type_code來限定合同並且訂單也有一個co_order_type_code。

我正在構建一個通用搜索,允許用戶根據很多字段進行選擇。 給我帶來麻煩的查詢是在合同或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秒行。

我會做一個外連接,但那會返回很多額外的行。

謝謝

回答

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()函數。

您在ndx_contract_orders上的主鍵實際上是一個問題。爲了做到這一點,你只需要通過contract_id查找,你需要顛倒該主索引的字段順序,只能通過contract_id啓用索引查找。或者,您可以爲co_contract_id添加一個附加索引。老實說,如果訂單ID是一個自動增量,這個領域本身應該可能是您的主要關鍵,並且co_contract_id字段應該只有它自己的索引。因爲order_id上的主鍵自動增量將確保唯一性,所以不需要在兩個字段中強制使用唯一索引。

+0

謝謝你,我因生產問題而被叫走了。我不想做一個獨特的原因是,在實際選擇中,我返回約25個合同領域,並加入客戶和地址表以使其他字段返回給用戶。 – sdfor 2013-04-09 21:15:45

+0

分離主鍵的第二點做了這項工作。我現在不到一秒鐘。謝謝!!! – sdfor 2013-04-09 21:29:24

相關問題