Есть селект с джойном следующего вида: left join table t on t.number = left(d.number, 6)
Т.е. number это некое число-идентификатор, но в таблице d оно хранится в более длинном формате. Поэтому при джойне я использую left для обрезки идентификатора до нужного кол-ва цифр, как он хранится в таблице t.
Проблема в том, что это дико замедляет запрос, происходит это потому что используется функция в условии джойна (с substring ситуация такая же).
Если бы это условие было дополнительным я бы мог вынести его в where и использовать что-то вроде: t.number like concat(left(d.number, 6), '%'), но никак.
Может есть еще какие-то варианты?)
В итоге я просто добавил один вложенный селект, в котором результат функции left в самом селекте как поле, а далее уже джойн по этому полю. Немного костыльно, может, но я уменьшил время выполнения примерно в ~20 раз))
Может кому пригодится:
select t.id
from ( select left(id, 6) as id from d ) a
left join t on t.id = a.id
Очень странный способ соединения...
Если бы это была выборка, то можно было бы построить индекс по функции (если СУБД позволяет), а для соединения - делайте денормализацию.
Ну, странный или нет, других вариантов просто нет) под денормализацией имеете в виду привести идентификатор в обеих таблицах к одному кол-ву цифр?)
тоже мысль, конечно, но я работаю с кхд, а не со своей небольшой бд, поэтому это как крайний вариант, который не факт, что возможен...
Илья, не важно большая или нет БД, вопрос в том, что можно вам с ней делать. Производительность ниоткуда не возьмётся, очевидно в вашем варианте теряем на преобразовании функцией, и от него нужно избавиться, поэтому что-то все равно придется создать - новый столбец, индекс или таблицу связей.
Константин Цветков, Илья, так это big data, тогда забудьте, что я написал, то касалось реляционных СУБД, здесь работайте как с big data, разделяете на стадии и распараллеливайте работу.