Оптимизация запроса поиска нескольких ветвей в структуре Nested Sets

Professor

Новичок
Добрый день.
Необходимо осуществлять поиск по городу и выводить полное дерево до него от области до города
Пример: Для города Железногорск нужно вывести:
Курская обл. Железногорский район, г Железногорск
Для поиска используются общедоступный кладры.
Единственное, я привел их в структуру Nested Sets, для более удобной работы.
Соответственно для поиска использую такой запрос:

Код:
SELECT * FROM core.delivery_kladr WHERE title LIKE "Железн%" AND `socr` IN ("г")
То есть ищу все города начинающиеся на "Железн"
Достаю их кладры и осуществляю поиск
Код:
SELECT
    `kladr`.`kladr` AS `key`, `kladr2` . *
FROM
    `delivery_kladr` AS `kladr`
        INNER JOIN
    `delivery_kladr` AS `kladr2` ON
        kladr2.lft <= kladr.lft AND kladr2.rgt >= kladr.rgt
WHERE
    (kladr.kladr IN ('5000000400000','4600700100000','7200100000600'))
Explain
Код:
# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
'1', 'SIMPLE', 'kladr', 'range', 'PRIMARY,r,l', 'PRIMARY', '39', NULL, '3', 'Using where'
'1', 'SIMPLE', 'kladr2', 'ALL', 'r,l', NULL, NULL, NULL, '205373', 'Range checked for each record (index map: 0x18)'
Индексы стоят на left и right (вообще, на время тестов поставил индексы на все, на что можно)

Пробовал ограничить выборку таким образом

Код:
SELECT
    `kladr`.`kladr` AS `key`, `kladr2` . *
FROM
    `delivery_kladr` AS `kladr`
        INNER JOIN
    `delivery_kladr` AS `kladr2` ON
        kladr2.lft <= kladr.lft AND kladr2.rgt >= kladr.rgt AND 
       kladr2.kladr_top IN ('50', '46', '72') AND 
      `kladr2`.kladr<=`kladr`.kladr
WHERE
    (kladr.kladr IN ('5000000400000','4600700100000','7200100000600'))
kladr_top - это первые 2 цифры кладра. То есть поиск только по нужному региону + найденные кладры всегда меньше кладра города, так ка ветвь идет вверх.

Индексы поставил опять же на все. Ситуация стала лучше, но все равно фиговая.
Код:
1, SIMPLE, kladr2, range, PRIMARY,r,l, index7, 9, , 28404, Range checked for each record (index map: 0x19)

Подскажите, как оптимизировать этот запрос.
 

Professor

Новичок
В общем получился такой запрос

Код:
SELECT 
    `kladr`.`kladr` AS `key`, `kladr2` . *
FROM
    `delivery_kladr` AS `kladr`
        INNER JOIN
    (SELECT 
        `delivery_kladr` . *
    FROM
        `delivery_kladr`
    WHERE
        (kladr_top IN ('02', '04', '12','13'))) AS `kladr2` ON kladr2.lft <= kladr.lft
        AND kladr2.rgt >= kladr.rgt
WHERE
    (kladr.kladr IN ('0200000109700' , '0200100111700',
        '0200200003800',
        '0200500012600',
        '0200700006500',
        '0201100007500',
        '0201200003600',
        '0201300002500',
        '0201500001000',
        '0201500004200',
        '0202700008300',
        '0202800000400',
        '0202900003400',
        '0202900008300',
        '0203200002400',
        '0203500008400',
        '0204400010000',
        '0205000001600',
        '0205900010200',
        '0400300000200',
        '1200200000300',
        '1201100000200',
        '1201400000500',
        '1300500000300',
        '1300800000300',
        '1301000000300',
        '1301600000500',
        '1301800000400',
        '1302000000600',
        '1302100000200'))
ORDER BY `kladr2`.`lft` ASC

Код:
# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
1, PRIMARY, kladr, range, PRIMARY,r,l, PRIMARY, 39, , 4, Using where; Using temporary; Using filesort
1, PRIMARY, <derived2>, ALL, , , , , 15725, Using where; Using join buffer
2, DERIVED, delivery_kladr, range, index7, index7, 9, , 27939, Using where
 
Сверху