Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL-Syntax und 'OR'-Performance

Jasons Antwort ist genau richtig. Außerdem würde ich versuchen, die modernere ANSI-Join-Syntax zu verwenden, um die Last von der WHERE-Klausel zu nehmen, um die Verwirrung dort zu beseitigen:

SELECT o.id
FROM programs o
JOIN titles_programs t ON t.object_id=o.id
JOIN descriptions_programs d ON d.object_id=o.id
WHERE MATCH (d.text) AGAINST ('+china' IN BOOLEAN MODE) AND d.current=1
OR MATCH (t.text) AGAINST ('+china' IN BOOLEAN MODE) AND t.current=1

Dadurch wird verhindert, dass die unbeabsichtigte Kreuzverbindung eine kombinatorische Explosion verursacht; Ich würde erwarten, dass es in angemessener Zeit funktioniert, es sei denn, die Datenbank ist wirklich riesig.

Wenn nicht, können Sie die Ergebnisse eines EXPLAIN SELECT des oben Gesagten posten? Vermutlich wird einer oder beide der Volltextindizes nicht verwendet. Ich könnte mir durchaus vorstellen, dass der Abfrageoptimierer den zweiten Volltextindex nicht verwendet, indem er versucht, die Zeilen auszufüllen, die nicht mit der ersten Volltextabfrage übereinstimmen, anstatt direkt zum Index zu gehen, oder so etwas.

Wenn Sie einen Volltextindex über zwei Spalten in Kombination erstellen möchten, erstellen Sie normalerweise einen Index über beide Spalten. Das geht auf jeden Fall viel schneller. Dies würde jedoch bedeuten, dass Sie Titel und Beschreibungen in dieselbe Tabelle einfügen müssen. Dies ist möglicherweise nicht so schwierig:Da Volltext nur auf MyISAM-Tabellen funktioniert (und Sie Ihre kanonischen Daten normalerweise nicht in MyISAM-Tabellen haben möchten), können Sie die endgültige Kopie Ihrer Daten in ordnungsgemäß normalisierten InnoDB-Tabellen mit einer zusätzlichen MyISAM-Tabelle aufbewahren enthält nur gestrippte und gestemmte Suchköder.

Wenn das alles nichts taugt... Nun, ich denke, ich würde zu dem von Ihnen erwähnten UNIONing zurückkehren, verbunden mit einem Filter auf Anwendungsebene, um doppelte IDs zu entfernen.