2012-09-18 65 views
0

我花了幾個小時來製作一個SQL查詢,該查詢執行一個JOIN並將兩列排序在一起,以我以前沒有處理的方式。下面是該查詢:加入/排序緩慢運行

SELECT `m`.`id`, `m`.`primary_category_id`, `m`.`primary_category_priority`, `m`.`description` 
FROM (`merchant` AS m) 
LEFT JOIN `merchant_category` 
    ON `merchant_category`.`merchant_id` = `m`.`id` 
WHERE 
    `merchant_category`.`category_id` = '2' 
    OR `m`.`primary_category_id` = '2' 
GROUP BY `m`.`id` 
ORDER BY 
    LEAST(merchant_category.priority = 0, `primary_category_priority` = 0) ASC, 
    LEAST(merchant_category.priority, `primary_category_priority`) ASC 
LIMIT 10 

它有兩列在一起,一個從merchant_category表,一個從商家表進行排序,讓他們一起排序。 merchant的每一行都有一個直接在表中引用的「主要」類別,以及存儲在merchant_category表中的零個或多個「輔助」類別。現在它可以正常工作,但速度很慢:通常會在我的生產數據庫上超過一分鐘。我想JOIN加上覆雜的排序是造成這個問題,但我能做什麼?

編輯下面是這兩個表的模式:

CREATE TABLE IF NOT EXISTS `merchant` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `name` varchar(100) CHARACTER SET utf8 NOT NULL, 
    `primary_category_id` int(11) NOT NULL, 
    `primary_category_priority` int(10) unsigned NOT NULL DEFAULT '0', 
    `description` mediumtext CHARACTER SET utf8 NOT NULL, 
    PRIMARY KEY (`id`) 
) 

CREATE TABLE IF NOT EXISTS `merchant_category` (
    `id` int(10) NOT NULL AUTO_INCREMENT, 
    `merchant_id` int(10) NOT NULL, 
    `category_id` int(10) NOT NULL, 
    `priority` int(10) unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`) 
) 
+0

您可以發佈表的架構專門'merchant'和'merchant_category'?也許你錯過了一些索引.. –

+0

你有索引設置正確嗎?兩個表中有多少行? – Erik

+0

@Erik'商家'有超過20,000我相信,'merchant_category'有幾倍。 – Jonah

回答

2

嘗試添加第二表的外鍵約束,

CREATE TABLE IF NOT EXISTS `merchant_category` (
    `id` int(10) NOT NULL AUTO_INCREMENT, 
    `merchant_id` int(10) NOT NULL, 
    `category_id` int(10) NOT NULL, 
    `priority` int(10) unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`), 
    CONSTRAINT mc_fk FOREIGN KEY (`merchant_id`) REFERENCES `merchant`(`id`) 
) 
+0

@Jonah你想排序什麼? –

+0

由兩個不同表中的優先級號碼組成。在主要類別的「merchant」表中,以及次要類別的「merchant_category」表中。 – Jonah

+0

好吧,我添加了外鍵約束,我希望我的查詢現在能更快運行嗎? – Jonah

1

你強迫它運行LEAST的每一行,以便對它進行排序(兩次!)。它不能爲此使用索引。

+0

你會推薦什麼作爲替代方案? – Jonah

+0

我不得不使用'LEAST'來整合這兩個數字,以便將它們整理在一起。 – Jonah

+0

另外兩個小評論。 'merchant_category'.'category_id' ='2''是不是'JOIN'的一部分?你應該有一個組合索引,包括你選擇的東西和主鍵,所以(primary_category_id,id)。一個'EXPLAIN'會在該表上顯示一個表掃描... –