zip111
Новичок
Здравствуйте.
есть пару вопросов по оптимизации запроса к базе.
В двух словах - таблица `prices` содержащая около 5 миллионов записей со стоимостью минуты телефонного разговора того или иного провайдера связи.
Таблица `pricelists` содержит группы цен, этих самых прайсов, с разницей по времени, когда их присылал оператор-поставщик.
Таблица billing_packs содержит названия поставщиков и имеет ключевую связь с таблицей `terminators`, в которой содержится тех информация о поставщиках.
Необходимо выбрать цены по тому или иному коду по таблице прайсов, отсортировать их от самого дешевого к самому дорогому и вывести таблицу. Необходимо учитывать, что пользователь вводит номер телефона, а система должна подобрать оптимальный код, который подходит для этого звонка и вывести конкретно этот код. Например:
ползьователь вводит номер 380501234567
в прайсах есть коды 38050, 3805, 38, так вот правильным будет нахождение кода 38050, как наиболее полного совпадения.
Поехали...
пробую так: (для просто будем считать, что пользователь ввел 38050)
Смотрим Explain
не круто, идет полный перебор прайсов, не подходит...
пробую махинировать с LIKE '38050%' (или например '38050' LIKE CONCAT() ) - тоже полный перебор, хотя я всегда думал, что база юзает индексы в любом случае при такой конструкции.
пробую регулярки - тоже полный перебор...
В общем пока идеи кончились.. подскажите плиз?
Второй вопрос такой:
мне нужно отобрать только те прайсы, у которых в таблице `pricelists` строка `activation_time` (datetime) уже наступило. пока что я сделал просто WHERE pricelists.activation_time >= NOW(), но это не совсем верно, так как может быть такая ситуация, что есть прайслисты от одного и того же поставщика, с датой активации например 2011-05-30 00:00:00 и 2011-06-03 00:00:00, то есть нужно выбрать только то, что фактически наступило (2011-05-30 00:00:00), а в случае с WHERE pricelists.activation_time >= NOW() выберет обе записи.
Тут пока вообще идей нет.
Заранее всем спасибо
есть пару вопросов по оптимизации запроса к базе.
В двух словах - таблица `prices` содержащая около 5 миллионов записей со стоимостью минуты телефонного разговора того или иного провайдера связи.
Таблица `pricelists` содержит группы цен, этих самых прайсов, с разницей по времени, когда их присылал оператор-поставщик.
Таблица billing_packs содержит названия поставщиков и имеет ключевую связь с таблицей `terminators`, в которой содержится тех информация о поставщиках.
Необходимо выбрать цены по тому или иному коду по таблице прайсов, отсортировать их от самого дешевого к самому дорогому и вывести таблицу. Необходимо учитывать, что пользователь вводит номер телефона, а система должна подобрать оптимальный код, который подходит для этого звонка и вывести конкретно этот код. Например:
ползьователь вводит номер 380501234567
в прайсах есть коды 38050, 3805, 38, так вот правильным будет нахождение кода 38050, как наиболее полного совпадения.
Поехали...
пробую так: (для просто будем считать, что пользователь ввел 38050)
в целом, запрос выводит почти то, что нужно, НО очень долго.SELECT * FROM config.terminators
LEFT JOIN config.billing_packs ON billing_packs.id = terminators.billing_pack_id
LEFT JOIN config.pricelists ON pricelists.billing_pack_id = billing_packs.id
LEFT JOIN config.prices ON prices.pricelist_id = pricelists.id
WHERE pricelists.activation_time >= NOW()
AND (
prices.code = (LEFT('38050',5) OR LEFT('38050',4) OR LEFT('38050',3) OR LEFT('38050',2) OR LEFT('38050',1))
)
AND prices.enabled = 'y'
Смотрим Explain
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE terminators ALL NULL NULL NULL NULL 73
1 SIMPLE billing_packs eq_ref PRIMARY PRIMARY 2 config.terminators.billing_pack_id 1 Using where
1 SIMPLE prices ALL pricelist_id NULL NULL NULL 4012929 Using where
1 SIMPLE pricelists eq_ref PRIMARY PRIMARY 2 config.prices.pricelist_id 1 Using where
не круто, идет полный перебор прайсов, не подходит...
пробую махинировать с LIKE '38050%' (или например '38050' LIKE CONCAT() ) - тоже полный перебор, хотя я всегда думал, что база юзает индексы в любом случае при такой конструкции.
пробую регулярки - тоже полный перебор...
В общем пока идеи кончились.. подскажите плиз?
Второй вопрос такой:
мне нужно отобрать только те прайсы, у которых в таблице `pricelists` строка `activation_time` (datetime) уже наступило. пока что я сделал просто WHERE pricelists.activation_time >= NOW(), но это не совсем верно, так как может быть такая ситуация, что есть прайслисты от одного и того же поставщика, с датой активации например 2011-05-30 00:00:00 и 2011-06-03 00:00:00, то есть нужно выбрать только то, что фактически наступило (2011-05-30 00:00:00), а в случае с WHERE pricelists.activation_time >= NOW() выберет обе записи.
Тут пока вообще идей нет.
Заранее всем спасибо