Задавайте вопросы, мы ответим
Вы не зашли.
Неактивен
Почему добавлены ид стран в таблице городов - чтоб юзер мог искать по городам, а я ему могла предложить на выбор страну(-ы) в подсказках
Неактивен
Shopen написал:
vasya написал:
Explain показывает, что объединение идет с таблицы tech_regions_positions и дополнительное условие на `country_id` ухудшает план, приводя к лишней проверке. (Using where во втором плане)
Как это к лишней? )
Это же все равно что искать в базе Ивановых, но если среди них искать еще и Андреев - то новое условие ухудшит план )))animegirl написал:
Значит убрать
Условие либо нужно либо нет, если результат не зависит от country_id - то зачем вообще это условие в запросе? Если country_id влияет на запрос - как вы его уберете, если оно необходимо для уточнения результата?
Я понял так, что нужны Андреи Ивановы, проживающие в Юрюписке. Причем заранее известно, что всех Ивановых в Юрюпинске зовут Андреями. Тогда мы можем решить задачу или проверкой фамилии у каждого жителя Юрюпинска (в этом случае проверка имени избыточна), или выбрать всех Ивановых Андреев и у каждого проверить место проживания.
Вопрос автора какой из методов быстрее. Ответ зависит от конкретных данных.
Неактивен
vasya написал:
animegirl написал:
Я ещё что подумала, есть смысл заменить
(25<=`tech_regions_positions`.`longitude_left` AND `tech_regions_positions`.`longitude_left`<=25)на(`tech_regions_positions`.`longitude_left` BETWEEN 25 AND 25)?Нет, это синонимы.
Если это синонимы, и вы говорите, что переделывать не стоит, я правильно понимаю, что если я бы заменила одно на другое, то мог бы не сработать индекс? Или есть другая причина?
Неактивен
Синонимы это значит без разницы, как писать.
Индекс не сработает целиком в случае если у вас будут не 25 и 25, а отличающиеся числа, например, 24 и 25. Это формы записи это не зависит.
Неактивен
Индексы не работают с знаками > <?
Неактивен
Видимо акцентировала своё внимание на другом, но сейчас вспомнила данный момент в той теме
Но имеет смысл оставить, так как ведь может и попасть на =, хотя при координатах я в этом сомневаюсь
Неактивен
animegirl написал:
Но имеет смысл оставить, так как ведь может и попасть на =, хотя при координатах я в этом сомневаюсь
Зависит от количества таких запросов. Если их будет мало, то и смысла нет никакого. Ненужные индексы тоже плохо.
Неактивен
Такие запросы это основа проекта, он на геопривязке основан (
Неактивен
animegirl написал:
Такие запросы это основа проекта(
какие такие запросы, вот такие -
Отредактированно Shopen (16.11.2012 16:58:09)
Неактивен
Запросы по координатам.
Их будет два типа
1. Поиск наложения одного прямоугольника на другой
2. Поиск точки в прямоугольнике
Неактивен
А если их сделать каждый самостоятельным?
Я не до конца поняла, вот эту фразу "Заканчивают на них работу."
То есть он использует один из них а дальше нет, или же как только видит такой знак сравнения сразу перестаёт использовать их? Если первый вариант, тогда всё-таки выходит предложение выше по вынесению каждой координаты в свой индекс, имеет смысл?
Неактивен
animegirl написал:
Запросы по координатам.
Их будет два типа
1. Поиск наложения одного прямоугольника на другой
2. Поиск точки в прямоугольнике
Посмотрите в сторону пространственных индексов
http://dev.mysql.com/doc/refman/5.5/en/ … sions.html
Неактивен
animegirl написал:
А если их сделать каждый самостоятельным?
Я не до конца поняла, вот эту фразу "Заканчивают на них работу."
То есть он использует один из них а дальше нет, или же как только видит такой знак сравнения сразу перестаёт использовать их? Если первый вариант, тогда всё-таки выходит предложение выше по вынесению каждой координаты в свой индекс, имеет смысл?
О чем вам Shopen с самого начала и говорил.
В случае составного индекса при операциях больше/меньше будет использована только первая часть индекса. В случае отдельных индексов MySQL хотя бы сможет выбрать наиболее селективный из них.
Неактивен
vasya написал:
animegirl написал:
Запросы по координатам.
Их будет два типа
1. Поиск наложения одного прямоугольника на другой
2. Поиск точки в прямоугольникеПосмотрите в сторону пространственных индексов
http://dev.mysql.com/doc/refman/5.5/en/ … sions.html
У меня с английским тугова-то. Я не смогла найти вид записи в Пойнтах, поняла, что там 2 координаты, но можно ли их делать флоат? И как я их получу обратно, в каком виде? У вас нету в закромах хорошего мануала по данной тематике?
Неактивен
Поищите гугле. Например, http://lib.rus.ec/b/328368/read Про качество ничего не скажу, не читал.
Неактивен
Спасибо, не поленилась, почитала, заодно не только о геометрии, но и много из остального, поняла, что коней на переправе не меняют, пускай это будет переделано в версии 2.0, а не на кануне сдачи первой версии )
Неактивен
animegirl написал:
Таблицы
Запрос вариант первый:
SELECT `tech_regions_positions`.`region_id`,`tech_regions_names`.`region_language`,IF(`region_language`='ur',0,IF(`region_language`='en',1,IF(`region_language`='cn',2,IF(`region_language`='es',3,IF(`region_language`='jp',4,IF(`region_language`='pt',5,IF(`region_language`='de',6,IF(`region_language`='fr',7,IF(`region_language`='ru',8,9))))))))) `language_priority`
Не в тему индексов:
1. Я бы region_language объявил ENUM-ом и не заставлял бы MYSQL 30000 раз в сутки вычислять 7 тупых IF-ов.
При этом varchar(7) изменится вообще на один байт. Причем en.... ru будет гарантировано "лежать" в виде хеша из 10 записей в RAM.
1a) Если region_lang больше чем 10, то дополнительно добавил бы поле default_region_lang в которое бы вписал описанные 10 значении.
1б) Я в этом не уверен, но ENUM между клиентом и сервером тоже будет передаваться в виде одно байта, и расшифровываться на стороне клиента ... Те по сети передастся байт 3... А на стороне клиента станет ES.
2. Я бы "сгладил" параметры ML+MT перед тем как передавать их в запрос, хотя бы до INT-а (те до целого числа градусов). Не уверен, что это правильно => Необходимо смотреть на данные...
Возможно требуется сгладить до INT и сами latitude....
И еще про FLOAT/DOUBLE/DECIMAL
http://tarlyun.com/mysql/xranenie-ne-ce … l-v-mysql/
Вот эти строчки ЧИТАТЬ:
SELECT money FROM test WHERE money = 123.34;
Empty set (0.00 sec)
2a) Сглаживание позволит чаще использовать КЭШ запрсов... Неужели вам важно:
>= 25.7298173
или
>= 25.7298172
Помоему вполне достаточно
>= 25.72
или даже
>= 25
3. А еще бы я добавил LIMIT 1, так как судя по задаче требуется автоматически определить ЯЗЫК по данным из GEO-СУБД, которая содержит данные IP-network => (геокоординаты). Или вы желает подсказать пользователю список ЯЗЫКОВ ?
4. Во второй запрос тоже можно добавить LIMIT 1 так как достаточно определить, что регион входит как минимум в один "квадрат координат", зачем узнавать что регион входит в N квадратов мне не понятно....
5. Зачем ключ по `region_name` вообще не понятно...
6. Так как база данных READONLy (те DataWareHouse), то в принципе не важно сколько индексов в ней будет.
Главное чтобы у MYSQL крышу не снесло при выборе тго или иного индекса.
7. Я бы поробовал поэкпериментировать с вот этим индексом:
KEY `city_GCS` (`latitude_top`,`latitude_bottom`,`longitude_left`,`longitude_right`)
Вам в принципе правильно посоветовали поделить его на 4 штуки.
Причем в данном случае может случиться, что значения будут взяты не из БД, а прямо из Индекса !
Можно попробовать вот так:
KEY `city_GCS1` (`latitude_top`,`latitude_bottom`)
KEY `city_GCS2` (`longitude_left`,`longitude_right`)
8. А еще я недопонял смысл вот этой инструкции:
(25<=`tech_regions_positions`.`longitude_left` AND `tech_regions_positions`.`longitude_left`<=25)
???
В чем тут смысл ?
Отредактированно федя (18.11.2012 12:39:07)
Неактивен
Ну и наконец самое важное:
Какой бы не был быстрый MYSQL, какое бы вы количество индексов не построили намного производительнее будет
организация промежуточного слоя "кэширования данных" (с использованием memcache или иного механизма).
Те весь земной шарик делите на 10000 регионов и стройте на прикладном уровне HASH:
X-Y => LANG
При приходе нового запроса X1, Y1 обращаетесь к СУБД и вносите в HASH еще одну запись...
Таким образом определение LANG для 30% пользователей (к примеру из региона МОСКВА) у вас будет вообще без обращения к СУБД (мгновенно получать ответ RU).
ps.
Но это в версии 2.1
Неактивен
федя написал:
animegirl написал:
Таблицы
Запрос вариант первый:
SELECT `tech_regions_positions`.`region_id`,`tech_regions_names`.`region_language`,IF(`region_language`='ur',0,IF(`region_language`='en',1,IF(`region_language`='cn',2,IF(`region_language`='es',3,IF(`region_language`='jp',4,IF(`region_language`='pt',5,IF(`region_language`='de',6,IF(`region_language`='fr',7,IF(`region_language`='ru',8,9))))))))) `language_priority`
Не в тему индексов:
1. Я бы region_language объявил ENUM-ом и не заставлял бы MYSQL 30000 раз в сутки вычислять 7 тупых IF-ов.
При этом varchar(7) изменится вообще на один байт. Причем en.... ru будет гарантировано "лежать" в виде хеша из 10 записей в RAM.
1a) Если region_lang больше чем 10, то дополнительно добавил бы поле default_region_lang в которое бы вписал описанные 10 значении.
1б) Я в этом не уверен, но ENUM между клиентом и сервером тоже будет передаваться в виде одно байта, и расшифровываться на стороне клиента ... Те по сети передастся байт 3... А на стороне клиента станет ES.
2. Я бы "сгладил" параметры ML+MT перед тем как передавать их в запрос, хотя бы до INT-а (те до целого числа градусов). Не уверен, что это правильно => Необходимо смотреть на данные...
Возможно требуется сгладить до INT и сами latitude....
И еще про FLOAT/DOUBLE/DECIMAL
http://tarlyun.com/mysql/xranenie-ne-ce … l-v-mysql/
Вот эти строчки ЧИТАТЬ:
SELECT money FROM test WHERE money = 123.34;
Empty set (0.00 sec)
2a) Сглаживание позволит чаще использовать КЭШ запрсов... Неужели вам важно:
>= 25.7298173
или
>= 25.7298172
Помоему вполне достаточно
>= 25.72
или даже
>= 25
3. А еще бы я добавил LIMIT 1, так как судя по задаче требуется автоматически определить ЯЗЫК по данным из GEO-СУБД, которая содержит данные IP-network => (геокоординаты). Или вы желает подсказать пользователю список ЯЗЫКОВ ?
4. Во второй запрос тоже можно добавить LIMIT 1 так как достаточно определить, что регион входит как минимум в один "квадрат координат", зачем узнавать что регион входит в N квадратов мне не понятно....
5. Зачем ключ по `region_name` вообще не понятно...
6. Так как база данных READONLy (те DataWareHouse), то в принципе не важно сколько индексов в ней будет.
Главное чтобы у MYSQL крышу не снесло при выборе тго или иного индекса.
7. Я бы поробовал поэкпериментировать с вот этим индексом:
KEY `city_GCS` (`latitude_top`,`latitude_bottom`,`longitude_left`,`longitude_right`)
Вам в принципе правильно посоветовали поделить его на 4 штуки.
Причем в данном случае может случиться, что значения будут взяты не из БД, а прямо из Индекса !
Можно попробовать вот так:
KEY `city_GCS1` (`latitude_top`,`latitude_bottom`)
KEY `city_GCS2` (`longitude_left`,`longitude_right`)
8. А еще я недопонял смысл вот этой инструкции:
(25<=`tech_regions_positions`.`longitude_left` AND `tech_regions_positions`.`longitude_left`<=25)
???
В чем тут смысл ?
1. Интересная, я раньше с этим типом вообще не сталкивалась, но вроде как очень даже подходит. Только одно НО языков много, на данный момент 187, и проблема в том, что по надобности будет добавление.
- можно сделать упграйд колонки енума?
- насколько это повесит ДБ если там уже будут миллионы записей?
2. Это как так сгладить до инта? Один градус это 111км на карте. Единственный вариант, это перед записью и запросами, отрезать самому 6 знаков и двигать запятую, но не экстрим разве?
2а. "25.7298173 или 25.7298172" это разница в 3 метра, в размерах прямоугольных площадей, это не сильно парит, в размерах точек, ещё можно потерпеть, но не совсем охота, особенно учитывая что точность геолакации в последние время, всё возрастает.
А вот уже
"Помоему вполне достаточно
>= 25.72
или даже
>= 25"
Так в первом варианте погрешность в 1км, во втором в 70км (Приблизительно в уме прикинула). А это уже никак не катит, даже если брать на уровне стран, так как есть страны, где эти 70км уже половина страны, причём даже не надо вспоминать ватикан, хватит Израиля того же.
3. Нет, язык известен до этого, есть список стран, на разных языках, юзер должен получить список стран (регионов, городов итп.) на своём языке, если на его языке нету записи то выдёргивать на том языке, который выше в таблице распространённости. И список ограничивается теми странами(далее "территории"), которые могут быть видны у него на карте. Остальное не надо.
4. Не совсем поняла, что и почему, но чуствую, что вывод был сделан из ошибочного представления логике, описаного в ответе на пункт 3
5. Обратный поиск, юзер пишет название нужной территории, ему возвращаются варианты.
6. База далеко не READONLY, она будет постоянно допиливаться, так, что динамика будет там, может не гигантская, но собрать такое количество данных дело времени.
7. уже переделала
8. в самом вернем варианте, вы можете увидеть, что там вариаблы из скрипта подставляются, меня попросили вписать туда цифры, я от балды и написала, а так там координаты левого и правого края карты, либо верхнего и нижнего. Короче даются 4 края, надо найти, всё, что хоть как-то находится внутри, не только полное вхождение, но и частичное тоже.
Неактивен
федя написал:
Ну и наконец самое важное:
Какой бы не был быстрый MYSQL, какое бы вы количество индексов не построили намного производительнее будет
организация промежуточного слоя "кэширования данных" (с использованием memcache или иного механизма).
Те весь земной шарик делите на 10000 регионов и стройте на прикладном уровне HASH:
X-Y => LANG
При приходе нового запроса X1, Y1 обращаетесь к СУБД и вносите в HASH еще одну запись...
Таким образом определение LANG для 30% пользователей (к примеру из региона МОСКВА) у вас будет вообще без обращения к СУБД (мгновенно получать ответ RU).
ps.
Но это в версии 2.1
Пункт 3, логика запроса не в этом
Неактивен
ENUM по возможности использовать не следует. Не смотря на свои преимущества с точки зрения места хранения на диске, он не является переносимым (ибо это фича mysql, а не sql) и весьма непрост в понимании и поддержке, относительно других типов данных, конечно же. И по сети передаются конечно не индексы, а уже данные, так что выигрыша тут тоже не будет. Не советую
сглаживать гео-координаты до второго знака после запятой - это жесть
кстати, если мне память не изменяет, в случае 4 индексов, mysql не только сможет выбирать самый селективный, но и при определенных обстоятельствах мерджить их.
Неактивен
Shopen написал:
ENUM по возможности использовать не следует. Не смотря на свои преимущества с точки зрения места хранения на диске, он не является переносимым (ибо это фича mysql, а не sql) и весьма непрост в понимании и поддержке, относительно других типов данных, конечно же.
То что ENUM это фича MySQL это понятно... Про переносимость тоже понятно...
Но в данном разделе речь идет про оптимизацию именно МySQL.
ENUM в MySQL это один из самых простых и доступных методов оптимизации.
Более того если запустить какой-нить "родной оптимизатор" он вообще предложит вам 90% колонок в ENUM преобразовать
ps.
Есть кстати еще и SET-ы, тоже очень полезная вещь для людей пишущих "горы IF/CASE внутри SQL".
Я то лично так вообще никогда так не делаю, так как намного проще HASH на перл-е написать
Shopen написал:
И по сети передаются конечно не индексы, а уже данные, так что выигрыша тут тоже не будет. Не советую
Речь идет не про "индексы которые передаются", а про то что:
Описание ENUM расположено в заголовке таблицы.
Клиент mysql может (должен) прочитать этог заголовок и запомнить
что AAA=1, BBB=2, ..... XXX=18
По сети могут передаваться один байт на каждый ENUM
2 2 18 18 1 2
А клиент их расшифровывать и отображать...
Делают ли так все клиенты, я не знаю... Но это одна из главных ФИЧ
Shopen написал:
сглаживать гео-координаты до второго знака после запятой - это жесть
Ну да если имется задача автоматически определить, что к нам зашла единственная жительница Камеруна говорящая на языке БИКЬЯ, то и 40 знаков после запятой не хватит
1 место: Самый редкий разговорный язык на нашей планете - это язык бикья. На нем говорит лишь одна 87-летняя женщина из деревни на границе между Камеруном и Нигерией.
Неактивен
ENUM оптимизирует строки в числа, т.е. по сути varchar/char в int. Поле типа CHAR(2) например переводить в ENUM совершенно бессмысленно, никакого выигрыша не будет ни в чем, ни при каком количестве вариантов >10. Основной смысл ENUM представить некий набор достаточно длинных строк в виде числовых индексов. Это оптимизирует место на диске, но не скорость (считаем что сравниваем проиндексированный длинный char и tinyint). Разница в скорости будет копеечная. Если не char а varchar то выигрыш чуть больше, но только в случае всех остальных столбцов FIXED-типа.
Делают ли так все клиенты, я не знаю...
Клиенты таких вещей не делают, они спрашивают SELECT field FROM table - и сервер возвращает им field. Клиент может запросить так SELECT field+0 FROM table, тогда сервер поймет что от него хотят числовой индекс и отдаст его - но это делается на уровне скрипта, а не через клиентскую библиотеку mysql. Опять же если речь об языках (RU,EN,US...) - то передавать индекс вместо значения - попросту напрасный труд, хотя может быть какие то оптимизаторы подскажут такую оптимизацию.
то и 40 знаков после запятой не хватит
Речь о геолокации, причем тут количество жителей и их язык? Вам уже написали, то два знака запятой - это потеря километра. И это уже никакая не геолокация, а черт знает что. Потому что 1 км - это может оказаться другая страна, что уж говорить про город или улицу
Неактивен