Frage

Hier ist meine Abfrage:

select word_id, count(sentence_id) 
from sentence_word 
group by word_id 
having count(sentence_id) > 100;

Die Tabelle sentenceword enthält drei Felder, wordid, sentenceid und einen Primärschlüssel-ID. Es hat 350k + Reihen. Diese Abfrage dauert eine satten 85 Sekunden und ich frage ich (in der Hoffnung, zu beten?) Gibt es einen schnellen Weg, um alle wordids zu finden, die mehr als 100 sentenceids hat.

Ich habe versucht, den select count Teil herausnehmen, und nur tun ‚count (1),‘ aber weder beschleunigt es auf.

würde ich jede Hilfe dankbar Sie verleihen können. Dank!

War es hilfreich?

Lösung

  

mit count (sentence_id)> 100;

Es gibt ein Problem mit diesem ... Entweder die Tabelle doppeltes Wort / Satzpaar, oder es funktioniert nicht.

Wenn es doppelte Wort / Satzpaare hat, sollen Sie diesen Code verwenden, die richtige Antwort zu bekommen:

HAVING COUNT(DISTINCT Sentence_ID) > 100

Wenn die Tabelle keine doppelten Wort- / Satzpaare hat ... dann sollten Sie nicht sentence_ids zählen, sollten Sie nur Zeilen zählen.

HAVING COUNT(*) > 100

In diesem Fall können Sie einen Index auf erstellen word_id nur , um eine optimale Leistung.

Andere Tipps

Wenn Sie noch kein Konto haben, erstellen Sie einen zusammengesetzten Index für sentence_id, word_id.

Wenn die Abfrage häufig durchgeführt wird, und die Tabelle selten aktualisiert, erhalten Sie eine Hilfstabelle mit Wort-IDs und entsprechenden Satz zählt halten konnte - hart darüber hinaus, dass jeder weitere Optimierung zu denken

Ihre Anfrage ist in Ordnung, aber es braucht ein wenig Hilfe (Indizes) zu schnellen Ergebnisse zu erzielen.

Ich habe nicht meine Ressourcen zur Hand (oder den Zugriff auf SQL), aber ich werde versuchen, Ihnen aus dem Gedächtnis zu helfen.

Konzeptionell ist die einzige Möglichkeit, diese Abfrage zu beantworten ist, alle Datensätze zu zählen, die die gleiche word_id teilen. Das bedeutet, dass die Abfrage-Engine eine schnelle Art und Weise muss die Datensätze zu finden. Ohne einen Index auf word_id, die Datenbank das einzige, was durch die Tabelle einen Datensatz zu einem Zeitpunkt gehen tun und halten Summen jedes einzelnen deutlichen word_id läuft es findet. Das würde erfordern in der Regel eine temporäre Tabelle und keine Ergebnisse können versendet werden, bis die gesamte Tabelle gescannt wird. Nicht gut.

Mit einem Index auf word_id, es hat immer noch durch den Tisch zu gehen, so Sie würden denken, es würde nicht viel helfen. Allerdings kann die SQL-Engine für jeden word_id die Zählung berechnet nun ohne bis zum Ende der Tabelle zu warten: es kann die Zeile versenden und die Zählung für diesen Wert von word_id (wenn es Ihre where Klausel geht), oder die Zeile verwerfen (wenn dies nicht der Fall); das wird im unteren Speicherlast auf dem Server führen, möglicherweise teilweise Antworten und die temporäre Tabelle wird nicht mehr benötigt. Ein zweiter Aspekt ist die Parallelität; mit einem Index auf word_id können SQL den Job in Stücke geteilt und separaten Prozessorkerne verwenden, um die Abfrage parallel (je nach Hardware-Fähigkeiten und vorhandene Workload).

laufen

Das könnte ausreichen, um Ihre Suche zu helfen; aber Sie werden versuchen, um zu sehen:

CREATE INDEX someindexname ON sentence_word (word_id)

(T-SQL-Syntax, man hat nicht angegeben, welche SQL-Produkt, das Sie verwenden)

Wenn das nicht genug ist (oder nicht helfen überhaupt), gibt es zwei weitere Lösungen.

Als erstes SQL können Sie die COUNT vorauszuberechnen (*) durch indizierte Sichten verwendet und andere Mechanismen. Ich habe nicht die Details bei der Hand (und ich nicht tun dies oft). Wenn Ihre Daten, ändert sich nicht häufig, dass würde Ihnen schnellere Ergebnisse, aber mit Kosten in Komplexität und ein wenig Speicher.

Auch könnten Sie in einer separaten Tabelle speichert die Ergebnisse der Abfrage zu berücksichtigen. Das ist nur sinnvoll, wenn die Daten nicht ändert, oder Änderungen an einem genauen Zeitplan (beispielsweise während einer Datenaktualisierung bei 2 Uhr morgens), oder wenn es sehr wenig ändert und Sie können mit nicht perfekten Ergebnissen für ein paar Stunden (Sie leben würde eine periodische Datenaktualisierung planen); das ist das moralische Äquivalent eines Arme-Leute-Data-Warehouse.

Der beste Weg, um sicher herauszufinden, was funktioniert für Sie die Abfrage und Blick auf die Abfrage-Plan mit und ohne einige Kandidatenindizes wie das oben ausgeführt werden.

Es ist überraschenderweise eine noch schnellere Art und Weise, dass auf große Datenmengen zu erreichen:

SELECT totals.word_id, totals.num 
  FROM (SELECT word_id, COUNT(*) AS num FROM sentence_word GROUP BY word_id) AS totals
 WHERE num > 1000;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top