2015-06-22 43 views
1

我有一個帶有「137678997」記錄且沒有唯一主鍵的表。這是我的表格描述。提高mysql雲查詢表的性能sql

+---------------+---------------+------+-----+---------+-------+ 
| Field   | Type   | Null | Key | Default | Extra | 
+---------------+---------------+------+-----+---------+-------+ 
| domain  | varchar(50) | YES | MUL | NULL |  | 
| guid   | varchar(100) | YES |  | NULL |  | 
| sid   | varchar(100) | YES | MUL | NULL |  | 
| url   | varchar(2500) | YES |  | NULL |  | 
| ip   | varchar(20) | YES |  | NULL |  | 
| is_new  | varchar(20) | YES |  | NULL |  | 
| ref   | varchar(50) | YES |  | NULL |  | 
| user_agent | varchar(255) | YES |  | NULL |  | 
| stats_time | datetime  | YES |  | NULL |  | 
| country  | varchar(50) | YES |  | NULL |  | 
| region  | varchar(50) | YES |  | NULL |  | 
| city   | varchar(50) | YES |  | NULL |  | 
| city_lat_long | varchar(50) | YES |  | NULL |  | 
| email   | varchar(100) | YES |  | NULL |  | 
+---------------+---------------+------+-----+---------+-------+ 

域,郵件索引,STATS_TIME

我的SQL查詢

SELECT p1.guid, p1.email,MAX(mx_time) as latest_time, 
     p1.city_lat_long, p1.user_agent, 
     p1.city, p1.region, p1.country 
FROM(
    SELECT guid, email, 
     MAX(stats_time)as mx_time, 
     city_lat_long, user_agent, 
     city, region, country 
    FROM page_views 
    WHERE domain ='our' 
     AND DATE(CONVERT_TZ(stats_time,'+00:00','+05:30')) 
     BETWEEN DATE('2013-06-21 00:00:00') 
     AND DATE('2013-08-21 00:00:00') 
    GROUP BY guid) p1 
WHERE p1.email !="" 
GROUP BY email 

UNION ALL 

SELECT p2.guid, p2.email, 
     mx_time, p2.city_lat_long, 
     p2.user_agent, p2.city, 
     p2.region, p2.country 
FROM(
    SELECT guid, email, 
     MAX(stats_time) as mx_time, 
     city_lat_long, user_agent, 
     city, region, country 
    FROM page_views 
    WHERE domain ='our' 
    AND DATE(CONVERT_TZ(stats_time,'+00:00','+05:30')) 
     BETWEEN DATE('2013-06-21 00:00:00') 
     AND DATE('2013-08-21 00:00:00') 
    GROUP BY guid) p2 
WHERE p2.email=""; 

對不起,這個大的查詢,其目的是獲得最新訪客(MAX(STATS_TIME))一個域名。在這裏我使用了UNION ALL,因爲我不得不通過電子郵件ID將所有匿名用戶分組。

我也做了一個簡單的選擇列沒有UNION ALL,這需要超過15分鐘的測試。我該如何提高我桌子上查詢的性能? 它實際上是一個帶有D2 Tier(1 GB RAM)的Google雲端SQL。真的很感謝你的建議,對於Mysql來說是非常新的。

編輯::

SELECT p2.guid, p2.email,mx_time, p2.city_lat_long, p2.user_agent, p2.city, p2.region, p2.country 
FROM 
(SELECT guid, email,MAX(stats_time)as mx_time, city_lat_long, user_agent, city, region, country FROM page_views WHERE domain ='our' AND DATE(CONVERT_TZ(stats_time,'+00:00','+05:30')) BETWEEN DATE('2013-06-21 00:00:00') AND DATE('2013-08-21 00:00:00') GROUP BY guid) p2 where p2.email="" 

該查詢給了我與誰亙古不具有郵件遊客行。

而且

SELECT p1.guid, p1.email,MAX(mx_time) as latest_time, p1.city_lat_long, p1.user_agent, p1.city, p1.region, p1.country 
FROM 
(SELECT guid, email,MAX(stats_time)as mx_time, city_lat_long, user_agent, city, region, country FROM page_views WHERE domain ='our' AND DATE(CONVERT_TZ(stats_time,'+00:00','+05:30')) BETWEEN DATE('2013-06-21 00:00:00') AND DATE('2013-08-21 00:00:00') GROUP BY guid) p1 where p1.email !="" GROUP BY email 

這一個給我這是不是空的,並通過電子郵件進行分組行。 而這兩者都是UNION ALL,因爲我需要在特定日期範圍內的所有匿名訪問者+已知訪問者(email!=「」)。

謝謝:)

+0

你在_Where_子句中有很多函數,對你的查詢有什麼不好,實際上Union All,Group By,你最好添加表結構和你的期望結果,我們將嘗試改變這個查詢 –

回答

0

1-您能通過電子郵件在內的查詢做過濾?

SELECT p1.guid, p1.email,MAX(mx_time) as latest_time, 
    p1.city_lat_long, p1.user_agent, 
    p1.city, p1.region, p1.country 
FROM(
SELECT guid, email, 
    MAX(stats_time)as mx_time, 
    city_lat_long, user_agent, 
    city, region, country 
FROM page_views 
WHERE domain ='our' 
    AND DATE(CONVERT_TZ(stats_time,'+00:00','+05:30')) 
    BETWEEN DATE('2013-06-21 00:00:00') 
    AND DATE('2013-08-21 00:00:00') and email !="" 
GROUP BY guid) p1 
WHERE p1.email !="" 
GROUP BY email 
UNION ALL 
SELECT guid, email, 
    MAX(stats_time) as mx_time, 
    city_lat_long, user_agent, 
    city, region, country 
FROM page_views 
    WHERE domain ='our' 
AND DATE(CONVERT_TZ(stats_time,'+00:00','+05:30')) 
    BETWEEN DATE('2013-06-21 00:00:00') 
    AND DATE('2013-08-21 00:00:00') and email ="" 
GROUP BY guid 

2-使用explain statement查看使用的執行計劃和索引。

3-在通過類似電子郵件過濾的其他字段上添加索引。我不知道域的基數(查詢中唯一的索引字段),但我認爲這不足以排除表中的大量數據以快速進行選擇。您可以使用show index查詢自己檢查其基數。

+0

Hi Adel ,感謝您及時的回覆 。 1.我不能通過電子郵件過濾,因爲它沒有提供之前查詢, 我將只有域名。但集團通過電子郵件是獲取唯一訪問者 –

1

很難提高查詢性能比較,因爲你有很多的功能Where子句什麼是壞對你的性能比較,最大功能和集團在子查詢我認爲這太糟糕,聯盟所有這一切都爲您提供了複製。其實我可以推薦你避免在條款Here有用的鏈接如何避免它的日期時間轉換。

,我想補充一些建議,你怎麼能一個域獲取最新遊客(MAX(STATS_TIME)),而最大和GROUP BY - 最好使用順序按書桌和限制

如果我誤解了你,你可以添加你的邏輯和預期的結果,我們將嘗試改變你的查詢。

謝謝。

更新

這是你的第一個查詢

SELECT p2.guid, p2.email,mx_time, p2.city_lat_long, p2.user_agent, p2.city, p2.region, p2.country 
FROM (SELECT guid, email,MAX(stats_time)as mx_time, 
        city_lat_long, user_agent, city, region, country 
     FROM page_views 
     WHERE domain ='our' 
      AND DATE(CONVERT_TZ(stats_time,'+00:00','+05:30')) 
      BETWEEN DATE('2013-06-21 00:00:00') AND DATE('2013-08-21 00:00:00') 
     GROUP BY guid) p2 
where p2.email="" 

你可以把它改成

SELECT guid, email,MAX(stats_time)as mx_time, city_lat_long, user_agent, city, region, country 
FROM page_views 
WHERE domain ='our' 
    AND DATE(CONVERT_TZ(stats_time,'+00:00','+05:30')) 
    BETWEEN DATE('2013-06-21 00:00:00') AND DATE('2013-08-21 00:00:00') 
    AND email="" 
GROUP BY guid 

此時你不需要兩個查詢只是和電子郵件= 「」至條款

更新II

應避免在數據轉換凡這樣DATE(CONVERT_TZ(stats_time,'+00:00','+05:30')) BETWEEN DATE('2013-06-21 00:00:00') AND DATE('2013-08-21 00:00:00')

CLAE我們能否將它更改爲stats_time > '2013-06-21 00:00:00' AND stats_time <= '2013-08-21 00:00:00'

正如我告訴你應該讀This Link這將是很好爲你!

+0

你好,感謝您的更快的反應, 我編輯我的帖子,讓我的意圖與查詢。請讓我知道如果可以改善更多。 –

+0

@vinay patlolla您需要爲所有訪客提供最後一次約會的第一個查詢,或者只需要最後一位訪客?因爲你使用Group by –

+0

嗨,我通過guid進行分組,其中我得到的結果是 與現有訪問者和匿名訪問者的行相結合。因此,從這個結果我需要唯一訪問者(第二個查詢來自編輯,其中只有上午通過電子郵件分組)和所有匿名人工智能(在編輯中的第一個查詢)。請讓我知道你是否需要任何澄清在此。謝謝 –