2017-02-27 90 views
1

我一直在閱讀很多很好的答案,在這個網站上的時間不同的問題,但這是我第一次發佈。所以提前感謝您的幫助。mySQL查詢優化瀏覽跟蹤器

這裏是我的問題:

我有一個MySQL的表跟蹤訪問不同的網站,我們有。這是表格結構:

create table navigation_base (
      uid int(11) NOT NULL, 
      date datetime not null, 
      dia date not null, 
      ip int(4) unsigned not null default 0, 
      session_id int unsigned not null, 
      cliente smallint unsigned not null default 0, 
      campaign mediumint unsigned not null default 0, 
      trackcookie int unsigned not null, 
      adgroup int unsigned not null default 0, 
      PRIMARY KEY (uid) 
    ) ENGINE=MyISAM; 

此表格有答案。 7000萬行(平均每天110,000)。

在我們創建的索引與下面的命令該表:

alter table navigation_base add index dia_cliente_campaign_ip (dia,cliente,campaign,ip); 
alter table navigation_base add index dia_cliente_campaign_ip_session (dia,cliente,campaign,ip,session_id); 
alter table navigation_base add index dia_cliente_campaign_ip_session_trackcookie (dia,cliente,campaign,ip,session_id,trackcookie); 

,我們使用此表來獲得由客戶,天,活動用下面的查詢分組訪客統計:

select 
    dia, 
    navigation_base.campaign, 
    navigation_base.cliente, 
    count(distinct ip) as visitas, 
    count(ip) as paginas_vistas, 
    count(distinct session_id) as sesiones, 
    count(distinct trackcookie) as cookies 
from navigation_base where 
    (dia between '2017-01-01' and '2017-01-31') 
    group by dia,cliente,campaign order by NULL 

即使創建了這些索引,一個月的響應時間也相對較慢;在我們的服務器上約3秒鐘。

有沒有加快這些查詢的一些方法?

在此先感謝。

回答

1

有了這麼多的數據,單獨編制索引可能沒有什麼幫助,因爲數據中有很多相似之處。除了你有GROUP BY和SORT以及聚合。所有這些結合在一起使得優化非常困難。 partitioning是前進的方向,這是因爲:

一些查詢可以在如下事實大大優化數據 滿足給定的WHERE子句只能在一個或多個 分區,其中自動排除任何剩餘的分區被存儲從 進行搜索。由於在創建分區 表後,可以更改分區,因此可以重新組織數據以增強 頻繁查詢,這些查詢在第一次設置分區方案時可能並不經常使用。

如果這不適合你,它仍然可能

此外,MySQL的5.7支持 查詢明確的分區選擇。例如,SELECT * FROM t PARTITION(p0,p1)WHERE c 僅選擇與WHERE 條件匹配的分區p0和p1中的那些行。

ALTER TABLE navigation_base 
     PARTITION BY RANGE(TO_DAYS(dia)) (
     PARTITION p0 VALUES LESS THAN (TO_DAYS('2018-12-31')), 
     PARTITION p1 VALUES LESS THAN (TO_DAYS('2017-12-31')), 
     PARTITION p2 VALUES LESS THAN (TO_DAYS('2016-12-31')), 
     PARTITION p3 VALUES LESS THAN (TO_DAYS('2015-12-31')), 
     .. 
     PARTITION p10 VALUES LESS THAN MAXVALUE)); 

使用更大或更小的分區,你認爲合適。

要記住的最重要的因素是mysql每個表只能使用一個索引。所以明智地選擇你的指數。

+0

嗨。謝謝你快速的回覆。前段時間嘗試分區,但沒有幫助。不過我會再試一次。我所做的只是創建一個包含一個月數據的表格,因爲這可能與某個分區類似。 Te查詢時間在大表和小表中相同。問候。 –

+0

我看到了你試過指標無分區的好處。單獨的桌子也不會更好。認爲它是這樣的:有多少_rows_需要讀(包括傳入了行),以滿足查詢。所有三種情況的答案都是一樣的。 –

1

如果你只在每天的粒度做COUNT(DISTINCT ...),然後建立和增量保持的彙總表。它將通過幾乎相同的SELECT,但只取昨天的數據查詢中的每個晚上增強。

然後用這個彙總表進行每月一次的「報告」。

More on Summary Tables

+0

嗨瑞克!呦讀我的心......或者我讀你;-)試圖Ÿ最終選擇了像你這樣的解決方案不同的方法之後。它就像是一個「動態ETL」,可以更新中間表。此表格包含按天,客戶和廣告系列的彙總數據。用戶每次執行查詢時,ETL(在PHP)查找日期不是在數據表中,並生成它們的飛行。感謝大家的幫助。問候 –