2016-08-02 4 views
0

Wir verwenden memsql 5.1 für ein Web-Analytics-Projekt. Es gibt ungefähr 80 Millionen Datensätze und 0,5 Millionen Datensätze pro Tag. Eine einfache Anfrage funktioniert ungefähr 5 Sekunden lang - wie viele Daten pro Domain, Geo, Sprache für einen bestimmten Tag empfangen wurden. Ich denke, es ist möglich, diese Zeit zu reduzieren, aber ich kann keinen Weg finden. Bitte sag mir den Weg.5 Sekunden pro Auswahl aus 80M Datensätzen in memsql

Tabellen wie ein

CREATE TABLE `domains` (
    `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    `geo` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 
    `lang` char(5) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 
    `browser` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 
    `os` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 
    `device` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 
    `domain` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 
    `ref` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 
    `blk_cnt` int(11) DEFAULT NULL, 
    KEY `date` (`date`,`geo`,`lang`,`domain`) /*!90619 USING CLUSTERED COLUMNSTORE */ 
    /*!90618 , SHARD KEY() */ 
    ) 

Anfrage wie diese:

memsql> explain SELECT domain, geo, lang, avg(blk_cnt) as blk_cnt, count(*) as cnt FROM domains WHERE date BETWEEN '2016-07-31 0:00' AND '2016-08-01 0:00' GROUP BY domain, geo, lang ORDER BY blk_cnt ASC limit 40; 
    +-------------------------------------------------------------------------------------------------------------------------------------------------------+ 
    | EXPLAIN                                      | 
    +-------------------------------------------------------------------------------------------------------------------------------------------------------+ 
    | Project [r0.domain, r0.geo, r0.lang, $0/CAST(COALESCE($1,0) AS SIGNED) AS blk_cnt, CAST(COALESCE($2,0) AS SIGNED) AS cnt]         | 
    | Top limit:40                                     | 
    | GatherMerge [SUM(r0.s)/CAST(COALESCE(SUM(r0.c),0) AS SIGNED)] partitions:all est_rows:40                 | 
    | Project [r0.domain, r0.geo, r0.lang, s/CAST(COALESCE(c,0) AS SIGNED) AS blk_cnt, CAST(COALESCE(cnt_1,0) AS SIGNED) AS cnt, s, c, cnt_1] est_rows:40 | 
    | TopSort limit:40 [SUM(r0.s)/CAST(COALESCE(SUM(r0.c),0) AS SIGNED)]                       | 
    | HashGroupBy [SUM(r0.s) AS s, SUM(r0.c) AS c, SUM(r0.cnt) AS cnt_1] groups:[r0.domain, r0.geo, r0.lang]              | 
    | TableScan r0 storage:list stream:no                               | 
    | Repartition [domains.domain, domains.geo, domains.lang, cnt, s, c] AS r0 shard_key:[domain, geo, lang] est_rows:40 est_select_cost:144350216   | 
    | HashGroupBy [COUNT(*) AS cnt, SUM(domains.blk_cnt) AS s, COUNT(domains.blk_cnt) AS c] groups:[domains.domain, domains.geo, domains.lang]    | 
    | Filter [domains.date >= '2016-07-31 0:00' AND domains.date <= '2016-08-01 0:00']                    | 
    | ColumnStoreScan scan_js_data.domains, KEY date (date, geo, lang, domain) USING CLUSTERED COLUMNSTORE est_table_rows:72175108 est_filtered:18043777 | 
    +-------------------------------------------------------------------------------------------------------------------------------------------------------+ 

Nach Anwendung der Empfehlungen

  • Zeit der ursprünglichen Abfrage - 5s
  • mit Zeitoptimierung - 3.7s
  • mit timestamp + shardkey - 2.6s

Vielen Dank!

+0

fügten wir mehr vCPU und: Zeit der ursprünglichen Abfrage - 5s mit Zeitoptimierung - 3.7s mit Zeitstempel + shardkey - 2.6s danke sehr passend! – Georgy

Antwort

0

Das Ausführen der Gruppe nach ist wahrscheinlich der teuerste Teil dieser Abfrage. Durch Verwenden eines Shard-Schlüssels, der mit der Gruppe übereinstimmt, d. H. SHARD KEY (domain, geo, lang), wird es der Gruppe ermöglicht, schneller ausgeführt zu werden.

+0

auch, Ändern Ihrer Filter von 'Datum ZWISCHEN '2016-07-31 0:00' UND '2016-08-01 0: 00'' bis' Datum ZWISCHEN Zeitstempel ('2016-07-31 0:00') UND Timestamp ('2016-08-01 0:00') sollte die Dinge verbessern. –

Verwandte Themen