Ich optimiere meine Abfragen und finde etwas, was ich nicht verstehen kann.Unterabfrage mehr Zeilen als nötig verarbeiten
ich die folgende Abfrage verwenden eine Reihe von Kategorien zu wählen, so dass sie mit einem Aliasnamen aus einer Tabelle mit alter und neue Aliase für Kategorien kombinieren:
SELECT `c`.`id` AS `category.id`,
(SELECT `alias`
FROM `aliases`
WHERE category_id = c.id
AND `old` = 0
AND `lang_id` = 1
ORDER BY `id` DESC
LIMIT 1) AS `category.alias`
FROM (`categories` AS c)
WHERE `c`.`status` = 1 AND `c`.`parent_id` = '11';
Es gibt nur 2 Kategorien mit einem Wert von 11 für parent_id
, so sollte es 2 Kategorien aus der Alias-Tabelle nachschlagen.
Dennoch, wenn ich EXPLAIN
verwenden sie sagt, es 48 Zeilen zu verarbeiten hat. Die Alias-Tabelle enthält ebenfalls 1 Eintrag pro Kategorie (in diesem Fall kann es mehr sein). Alles ist indiziert und wenn ich es richtig verstehe, sollte es sofort den richtigen Alias finden.
Jetzt ist hier die seltsame Sache. Wenn ich die Aliase nicht nach Kategorien aus den Bedingungen, sondern manuell nach den Kategorie-IDs vergleiche, die die Abfrage zurückgibt, verarbeitet sie nur eine Zeile, wie mit dem Index beabsichtigt.
Also ersetze ich WHERE category_id = c.id
durch WHERE category_id IN (37, 43)
und die Abfrage wird schneller:
Das einzige, was ich denken kann, ist, dass die Unterabfrage nicht über die Ergebnisse der Abfrage ausgeführt wird, aber vor einigen Filtern erledigt. Jede Art von Erklärung oder Hilfe ist willkommen!
Edit: alberne mich, die WHERE IN
funktioniert nicht, da es keine eindeutige Auswahl macht. Die Frage steht immer noch!
erstellen Tabellenschema
CREATE TABLE `aliases` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lang_id` int(2) unsigned NOT NULL DEFAULT '1',
`alias` varchar(255) DEFAULT NULL,
`product_id` int(10) unsigned DEFAULT NULL,
`category_id` int(10) unsigned DEFAULT NULL,
`brand_id` int(10) unsigned DEFAULT NULL,
`page_id` int(10) unsigned DEFAULT NULL,
`campaign_id` int(10) unsigned DEFAULT NULL,
`old` tinyint(1) unsigned DEFAULT '0',
PRIMARY KEY (`id`),
KEY `product_id` (`product_id`),
KEY `category_id` (`category_id`),
KEY `page_id` (`page_id`),
KEY `alias_product_id` (`product_id`,`alias`),
KEY `alias_category_id` (`category_id`,`alias`),
KEY `alias_page_id` (`page_id`,`alias`),
KEY `alias_brand_id` (`brand_id`,`alias`),
KEY `alias_product_id_old` (`alias`,`product_id`,`old`),
KEY `alias_category_id_old` (`alias`,`category_id`,`old`),
KEY `alias_brand_id_old` (`alias`,`brand_id`,`old`),
KEY `alias_page_id_old` (`alias`,`page_id`,`old`),
KEY `lang_brand_old` (`lang_id`,`brand_id`,`old`),
KEY `id_category_id_lang_id_old` (`lang_id`,`old`,`id`,`category_id`)
) ENGINE=InnoDB AUTO_INCREMENT=112392 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
Eh? Das Schema stimmt nicht mit dem 'SELECT' überein - wo sind' status' und 'parent_id'? –
'status' und' parent_id' stammen aus der Haupttabelle ('categories'), nicht die Unterabfrage (beachten Sie den' c' Alias) – Tumtum