2016-06-06 17 views
0

zu optimieren Ich suche die folgende MySQL Stored Procedure zu optimieren für eine Art und Weise:Ist es möglich, diese MySQL-Abfrage

DECLARE total BIGINT UNSIGNED; 

    DROP TEMPORARY TABLE IF EXISTS tempTable; 
    CREATE TEMPORARY TABLE tempTable(identityValue BIGINT(20) UNSIGNED); 

    INSERT INTO tempTable 
    SELECT 
    `getIdentity`(samples.`originalId`) 
    FROM 
     `rawData` 
    WHERE 
    `samples`.`groupId` = _group; 


    SET total = (

    SELECT 
     IFNULL(SUM(getTotal(rawData.id, NULL, NULL)), 0) 

    FROM 
     rawData 

    WHERE 
     rawData.user= _user AND 
     getIdentity(rawData.id) IN (SELECT * FROM tempTable) 

    ); 


    DROP TEMPORARY TABLE IF EXISTS tempTable; 

    RETURN total; 

Die getIdentity Funktion sieht wie folgt aus:

RETURN (SELECT IFNULL(MIN(id1), _id) 
      FROM `equivalences` WHERE 
      id1 = _id OR id2 = _id); 

Die getTotal Funktion sieht so aus:

BEGIN 
    DECLARE total INT; 

    IF (_startDate IS NULL OR _endDate IS NULL) THEN 

     SET total = (SELECT IFNULL(SUM(ops.downloads),0) 
        FROM objects, ops 
        WHERE objects.id = _objectId AND ops.objectId = _objectId); 
    ELSE 
     SET total = (SELECT IFNULL(SUM(ops.downloads),0) 
        FROM objects, ops 
        WHERE objects.id = _objectId AND ops.objectId = _objectId AND 
          ops.`date` BETWEEN _startDate AND _endDate); 
    END IF; 

    RETURN total; 
END 

Momentan dauert es ~ 350ms zu laufen. Die meiste Zeit scheint sich auf die temporären Tabellen zu beziehen, die ich erstelle. Die Tabellen enthalten bereits die Indizes, die nach der Verwendung von EXPLAIN als notwendig erachtet wurden.

+0

Wie 'Proben' definiert ist? – amaksr

Antwort

1

Ich vermute, Sie verwenden keinen Speicher für temporäre Tabellen. Versuchen

CREATE TEMPORARY TABLE tempTable(identityValue BIGINT(20) UNSIGNED) engine=memory; 

Für mysql> = 5.6 Sie default_tmp_storage_engine=MEMORY in der Config festlegen, dass eine dauerhafte Option zu machen.

Da Sie bereits gute Indizes haben, hängt es von der Datenmenge in Ihrer temporären Tabelle ab, ob es sinnvoll ist, die Optimierung des Rests Ihrer Abfrage zu analysieren.

+0

Vorsicht ... Wenn Sie eine große temporäre Tabelle benötigen, stürzt die Abfrage ab. –

0

Verwenden Sie nicht IN (SELECT ...), verwenden Sie stattdessen einen JOIN. Dann loswerden TempTable, indem Sie es als Unterabfrage verwenden: JOIN (SELECT ...) mit, was einmal der Körper von TempTable war.

Verwenden Sie nicht "Kommajoin", verwenden Sie explizit JOIN ... ON.

Haben INDEX(objectId, date) und .

Die Verwendung einer MEMORY Tabelle für Zeitfenster ist gefährlich, da Sie den Wert max_heap_table_size, den Sie benötigen, nicht vorhersagen können. Und wenn es zu groß eingestellt wird, könnte RAM gestohlen werden, wodurch alles verlangsamt wird.