Ich habe die folgende Abfrage mit einer Unterabfrage und Selbst verbinden:Optimierung der Abfrage mit Abdeckung Indizes
SELECT bucket.patient_sid AS sid
FROM
(SELECT clinical_data.patient_sid,
clinical_data.lft,
clinical_data.rgt
FROM clinical_data INNER JOIN
(SELECT clinical_data.patient_sid,
clinical_data.lft,
clinical_data.rgt,
clinical_data.attribute_id
FROM clinical_data
WHERE clinical_data.attribute_id = '33' AND clinical_data.string_value = '2160-0') AS attribute
ON clinical_data.patient_sid = attribute.patient_sid
AND clinical_data.lft >= attribute.lft
AND clinical_data.rgt <= attribute.rgt
WHERE clinical_data.attribute_id = '36') AS bucket;
Ich habe in den folgenden Indizes auf diese definiert:
KEY `idx_bucket` (`attribute_id`,`string_value`)
KEY `idx_self_join` (`patient_sid`,`attribute_id`,`lft`,`rgt`)
Wenn ich mir die Abfrage Mit EXPLAIN ist die Unterabfrage, die den Deckungsindex idx_bucket verwendet, definitiv optimiert, aber die self-join-und where-Klausel nicht. Darüber hinaus, warum meldet es, dass nur patient_sid
und attribute_id
für used_key_parts
verwendet werden, während eine attachment_condition
für lft
, rgt
(Was bedeutet das?). Sowohl lft
als auch 'rgt` sind nur als Ganzzahlen ohne besondere Eigenschaften definiert, also warum werden sie nicht in meinem Deckungsindex verwendet?
Noch seltsamer ist, wenn ich definieren
KEY `idx_self_join` (`patient_sid`,`lft`,`rgt`,`attribute_id`)
nur patient_sid
registriert in used_key_parts.
filtered
Außerdem Tropfen auf 1.60%
von 11.00%
!
{
"query_block": {
"select_id": 1,
"cost_info": {
"query_cost": "645186.71"
},
"nested_loop": [
{
"table": {
"table_name": "clinical_data",
"access_type": "ref",
"possible_keys": [
"fk_attribute_idx",
"idx_value_string",
"idx_value_double",
"idx_bucket",
"idx_self_join_idx"
],
"key": "idx_bucket",
"used_key_parts": [
"attribute_id",
"string_value"
],
"key_length": "308",
"ref": [
"const",
"const"
],
"rows_examined_per_scan": 126402,
"rows_produced_per_join": 126402,
"filtered": "100.00",
"cost_info": {
"read_cost": "126402.00",
"eval_cost": "25280.40",
"prefix_cost": "151682.40",
"data_read_per_join": "46M"
},
"used_columns": [
"patient_sid",
"string_value",
"attribute_id",
"lft",
"rgt"
],
"attached_condition": "(`ns_large2`.`clinical_data`.`patient_sid` is not null)"
}
},
{
"table": {
"table_name": "clinical_data",
"access_type": "ref",
"possible_keys": [
"fk_attribute_idx",
"idx_value_string",
"idx_value_double",
"idx_bucket",
"idx_self_join_idx"
],
"key": "idx_self_join_idx",
"used_key_parts": [
"attribute_id",
"patient_sid"
],
"key_length": "10",
"ref": [
"const",
"ns_large2.clinical_data.patient_sid"
],
"rows_examined_per_scan": 14,
"rows_produced_per_join": 201169,
"filtered": "11.11",
"using_index": true,
"cost_info": {
"read_cost": "131327.39",
"eval_cost": "40233.83",
"prefix_cost": "645186.71",
"data_read_per_join": "73M"
},
"used_columns": [
"patient_sid",
"attribute_id",
"lft",
"rgt"
],
"attached_condition": "((`ns_large2`.`clinical_data`.`lft` >= `ns_large2`.`clinical_data`.`lft`) and (`ns_large2`.`clinical_data`.`rgt` <= `ns_large2`.`clinical_data`.`rgt`))"
}
}
]
}
}
Richtig, aber 'lft' und' rgt' definieren die Kanten der verschachtelten Menge, was mir eine Menge von Datensätzen gibt. Ihre Abfrage würde nicht die richtigen Ergebnisse liefern. Ich könnte 'lft' und' rgt's Bereichsberechnungen in die Where-Klausel schreiben, aber das wäre wahrscheinlich auch nicht optimal. –
Ich habe das alles nicht zur besseren Übersicht hinzugefügt. Sie können es immer noch hinzufügen. Oder nur einen Moment und ich werde für dich. – dkretz
Erledigt: Das Verschieben dieser Werte in die where-Klausel wurde gerade von ungefähr 20 Sekunden von der Ausführungszeit entfernt. –