2016-11-14 1 views
0

Wir wissen, dass wir Index eine Spalte Leistung zu verbessern, wenn wir nach dieser Spalte in einer WHERE-Anweisung filtern, aber wenn wir etwas tun, wie:Fügen Sie Indizes in MySQL für Felder hinzu, die in SELECT nicht WHERE verwendet werden, verbessert etwas?

SELECT 
    customer_id, 
    SUM(principal_lent) AS lifetime_total_loans, 
    SUM(IF(loan_created_at >= DATE_SUB(NOW(),INTERVAL 1 YEAR) and loan_created_at <= NOW(), principal_lent, 0)) AS yearly_total_loans, 
    SUM(IF(loan_created_at >= DATE_SUB(NOW(),INTERVAL 90 DAY) and loan_created_at <= NOW(), principal_lent, 0)) AS quarterly_total_loans, 
    SUM(IF(loan_created_at >= DATE_SUB(NOW(),INTERVAL 30 DAY) and loan_created_at <= NOW(), principal_lent, 0)) AS monthly_total_loans, 
    SUM(IF(loan_created_at >= CAST(DATE_FORMAT(NOW() ,'%Y-%m-01') as DATE) and loan_created_at <= NOW(), principal_lent, 0)) AS current_month_total_loans, 
    COUNT(id) AS lifetime_num_loans, 
    SUM(IF(loan_created_at >= DATE_SUB(NOW(),INTERVAL 1 YEAR) and loan_created_at <= NOW(), 1, 0)) AS yearly_num_loans, 
    SUM(IF(loan_created_at >= DATE_SUB(NOW(),INTERVAL 90 DAY) and loan_created_at <= NOW(), 1, 0)) AS quarterly_num_loans, 
    SUM(IF(loan_created_at >= DATE_SUB(NOW(),INTERVAL 30 DAY) and loan_created_at <= NOW(), 1, 0)) AS monthly_num_loans, 
    SUM(IF(loan_created_at >= CAST(DATE_FORMAT(NOW() ,'%Y-%m-01') as DATE) and loan_created_at <= NOW(), 1, 0)) AS current_month_num_loans 
FROM loans 
GROUP BY customer_id 

Das Feld customer_id ist ein FK so ist es indiziert.

Wenn ich Index loan_created_at, wird es einen Unterschied? Wie kann ich die Leistung verbessern? Danke

+0

Indizierung wirklich hilft Ihnen nur in der WHERE-Klausel und in JOIN-Bedingungen (wenn Sie beitreten auf ein Feld, das kein PK oder FK ist). In Ihrem Fall würde ich empfehlen, die Daten in einer anderen Tabelle zu speichern, die Sie täglich mit einem Cron-Job aktualisieren. –

+0

Die einzige Möglichkeit, die Leistung hier möglicherweise zu verbessern, ist, einen nächtlichen Job zu haben, der (Frühmorgens identifiziert das Alter/die Gruppe), dann müssen Sie nicht alle Berechnungen auf die Abfrage jedes Mal, wenn es ausgeführt wird; aber einmal jede Nacht. Alle "Neu/Null-Werte" wären neu erstellte Kredite und fallen in den aktuellen Monat. Alternativ könnten Sie jede Nacht eine Tabelle mit den Ergebnissen der Abfrage und UNION & Sum in "neu" generieren, so dass der Overhead nur für die neuen Datensätze gilt. – xQbert

+1

Es gibt eine Frage, die gestellt werden muss: Wenn Sie die obige Abfrage ausführen, wie hoch ist die Antwortzeit, die Sie erhalten? Eine zweite Frage lautet: Warum Sie nach Daten ohne Limit suchen sollten (ich meine, es scheint vernünftig zu sagen, dass Sie nur nach Daten suchen würden, die höchstens 1 Jahr alt oder 6 Monate alt sind, oder irgendeinen anderen Zeitraum) . Wenn Sie wirklich auf den Anfang der Geschichte zurückblicken müssen, sollten Sie einige Ihrer Daten "kochen", wie @xQbert es empfiehlt. – FDavidov

Antwort

0

Ohne irgendeine Filterung und mit irgendwelchen anderen Dingen, die nützlich sein könnten, wird diese Abfrage über einen Tabellenscan durchgeführt. Das bedeutet, dass alle Zeilen in der Reihenfolge gelesen werden, in der sie für den Optimierer geeignet sind. Es kann eine temporäre Tabelle und eine Sortierung geben, um die GROUP BY durchzuführen. Das könnte nur vermieden werden, wenn die PRIMARY KEY mit customer_id startet, was ich bezweifle.

Wollen Sie wirklich DATE_SUB(NOW(),INTERVAL... wollen? Das fängt in der Mitte eines Tages in der Vergangenheit an. Führen Sie dieselbe Abfrage eine Minute später aus, und die Werte können sich erhöhen oder verringern. Wenn Sie mit den Kalendertagen zufrieden waren, ändern Sie NOW() in CURRENT_DATE(). An diesem Punkt könnten Sie vielleicht eine Übersichtstabelle mit Zählungen und Zwischensummen für jeden Tag erstellen. Aktualisieren Sie diese Tabelle jede Nacht, um die gestrigen Daten widerzuspiegeln. Ändern Sie dann diese 'Bericht'-Abfrage, um die Übersichtstabelle zu verwenden. Es wird wahrscheinlich viel schneller sein.

Mit Weiteren Informationen zum Filtern und die CREATE TABLE, könnten wir in der Lage sein, mehr Einzelheiten zu geben.

Verwandte Themen