2012-06-08 52 views
0

我有一個查詢,基本上結合了行動表,並按時間順序選擇,同時保留分頁。MySQL查詢效率 - 有沒有更好的方法?

有沒有更高效/更好的方法來做到這一點?查詢需要3秒鐘。不可怕..但我認爲有改進的空間,我會很多使用它..

謝謝!

SELECT 
    `newsletters_subscribers`.`email`, 
    `newsletters_subscribers`.`first_name`, 
    `newsletters_subscribers`.`last_name`, 
    `newsletters_subscribers`.`id` AS subscriber_id, 
    COUNT(DISTINCT newsletters_opens.id) AS opens, 
    COUNT(DISTINCT newsletters_clicks.id) AS clicks, 
    COUNT(DISTINCT newsletters_forwards.id) AS forwards 
FROM `thebookrackqccom_newsletters_subscribers` newsletters_subscribers 
    LEFT JOIN 
    `thebookrackqccom_newsletters_opens` newsletters_opens 
     ON `newsletters_opens`.`subscriber_id` = `newsletters_subscribers`.`id` 
     AND newsletters_opens.newsletter_id = 1 
    LEFT JOIN 
    `thebookrackqccom_newsletters_clicks` newsletters_clicks 
     ON `newsletters_clicks`.`subscriber_id` = `newsletters_subscribers`.`id` 
     AND newsletters_clicks.newsletter_id = 1 
    LEFT JOIN 
    `thebookrackqccom_newsletters_forwards` newsletters_forwards 
     ON `newsletters_forwards`.`subscriber_id` = `newsletters_subscribers`.`id` 
     AND newsletters_forwards.newsletter_id = 1 
WHERE 
    (newsletters_opens.id IS NOT NULL 
    OR newsletters_clicks.id IS NOT NULL 
    OR newsletters_forwards.id IS NOT NULL) 
GROUP BY 
    `newsletters_subscribers`.`id` 
ORDER BY 
    `newsletters_subscribers`.`email` ASC 
LIMIT 25 
+3

你有使用'EXPLAIN'看看是怎麼回事?確保您有正確的索引以確保良好的性能。 –

+0

請發佈EXPLAIN語句的結果,以便我們看看。 – Namphibian

+0

+1。通過改變指數,我的查詢從30秒到0.03秒。 – danneth

回答

1

你需要的是索引,查詢可以使用。三個表中的每一個上的(newsletter_id, subscribe_id)上的複合索引都會有所幫助。

您也可以重寫本查詢:

SELECT 
    s.email, 
    s.first_name, 
    s.last_name, 
    s.id    AS subscriber_id, 
    COALESCE(o.opens, 0) AS opens, 
    COALESCE(c.clicks, 0) AS clicks, 
    COALESCE(f.forwards, 0) AS forwards 
FROM thebookrackqccom_newsletters_subscribers AS s 
    LEFT JOIN 
    (SELECT subscriber_id, 
      COUNT(*) AS opens 
     FROM thebookrackqccom_newsletters_opens 
     WHERE newsletters_opens.newsletter_id = 1 
    ) AS o ON o.subscriber_id = s.id 
    LEFT JOIN 
    (SELECT subscriber_id, 
      COUNT(*) AS clicks 
     FROM thebookrackqccom_newsletters_clicks 
     WHERE newsletter_id = 1 
    ) AS c ON c.subscriber_id = s.id 
    LEFT JOIN 
    (SELECT subscriber_id, 
      COUNT(*) AS forwards 
     FROM thebookrackqccom_newsletters_forwards 
     WHERE newsletter_id = 1 
    ) AS f ON f.subscriber_id = s.id 
WHERE (o.subscriber_id IS NOT NULL 
    OR c.subscriber_id IS NOT NULL 
    OR f.subscriber_id IS NOT NULL) 
ORDER BY 
    s.email ASC 
LIMIT 25 
+0

索引它將其降低到不到十分之一秒。大!謝謝。建立索引有什麼好的經驗法則? –

+1

沒有簡單的索引路徑。從這個偉大的網站開始:[使用索引,盧克!](http://use-the-index-luke.com/) –

0

嘗試此查詢我希望你得到一個更好的執行時間

QUERY

SELECT 
`newsletters_subscribers`.`email`, 
`newsletters_subscribers`.`first_name`, 
`newsletters_subscribers`.`last_name`, 
`newsletters_subscribers`.`id` AS subscriber_id, 
@nopen := coalesce(N_OPEN.NOPENIDCOUNT, 000000) as opens, 
@nclick := coalesce(N_CLICK.NCLICKIDCOUNT, 000000) as clicks, 
@nfwd := coalesce(N_FWD.NFWDIDCOUNT, 000000) as forwards 

FROM 
(select @nopen := 0,@nclick := 0,@nfwd :=0) sqlvars, 

`thebookrackqccom_newsletters_subscribers` AS newsletters_subscribers 

LEFT JOIN (SELECT `newsletters_opens`.`subscriber_id`, 
COUNT(newsletters_opens.id) AS NOPENIDCOUNT 
FROM `thebookrackqccom_newsletters_opens` AS newsletters_opens 
WHERE newsletters_opens.newsletter_id = 1) AS N_OPEN 
ON N_OPEN.subscriber_id = `newsletters_subscribers`.`id` 


LEFT JOIN (SELECT `newsletters_clicks`.`subscriber_id`, 
COUNT(newsletters_clicks.id) AS NCLICKIDCOUNT 
FROM `thebookrackqccom_newsletters_clicks` AS newsletters_clicks 
WHERE newsletters_clicks.newsletter_id = 1) AS N_CLICK 
ON N_CLICK.subscriber_id = `newsletters_subscribers`.`id` 


LEFT JOIN (SELECT `newsletters_forwards`.`subscriber_id`, 
COUNT(newsletters_forwards.id) AS NFWDIDCOUNT 
FROM `thebookrackqccom_newsletters_forwards` AS newsletters_forwards 
WHERE newsletters_forwards.newsletter_id = 1) AS N_FWD 
ON N_FWD.subscriber_id = `newsletters_subscribers`.`id` 

GROUP BY `newsletters_subscribers`.`id` 
ORDER BY `newsletters_subscribers`.`email` ASC 
LIMIT 25 
相關問題