SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#26 15.11.2012 18:45:31

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?


-- --------------------------------------------------------

--
-- Table structure for table `tech_cities_names`
--

CREATE TABLE IF NOT EXISTS `tech_cities_names` (
  `city_id` int(10) unsigned NOT NULL,
  `region_id` mediumint(8) unsigned NOT NULL,
  `country_id` smallint(5) unsigned NOT NULL,
  `city_language` char(2) COLLATE utf8_unicode_ci NOT NULL,
  `city_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`city_id`,`city_language`),
  KEY `city_name` (`city_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- --------------------------------------------------------

--
-- Table structure for table `tech_cities_positions`
--

CREATE TABLE IF NOT EXISTS `tech_cities_positions` (
  `city_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `latitude_top` double(9,6) NOT NULL,
  `latitude_bottom` double(9,6) NOT NULL,
  `longitude_left` double(9,6) NOT NULL,
  `longitude_right` double(9,6) NOT NULL,
  PRIMARY KEY (`city_id`),
  KEY `city_GCS` (`latitude_top`,`latitude_bottom`,`longitude_left`,`longitude_right`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ;

-- --------------------------------------------------------

--
-- Table structure for table `tech_countrys_names`
--

CREATE TABLE IF NOT EXISTS `tech_countrys_names` (
  `country_id` smallint(5) unsigned NOT NULL,
  `country_language` char(2) COLLATE utf8_unicode_ci NOT NULL,
  `country_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`country_id`,`country_language`),
  KEY `country_name` (`country_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- --------------------------------------------------------

--
-- Table structure for table `tech_countrys_positions`
--

CREATE TABLE IF NOT EXISTS `tech_countrys_positions` (
  `country_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `latitude_top` double(9,6) NOT NULL,
  `latitude_bottom` double(9,6) NOT NULL,
  `longitude_left` double(9,6) NOT NULL,
  `longitude_right` double(9,6) NOT NULL,
  PRIMARY KEY (`country_id`),
  KEY `country_GCS` (`latitude_top`,`latitude_bottom`,`longitude_left`,`longitude_right`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;

-- --------------------------------------------------------

--
-- Table structure for table `tech_regions_names`
--

CREATE TABLE IF NOT EXISTS `tech_regions_names` (
  `region_id` mediumint(8) unsigned NOT NULL,
  `country_id` smallint(5) unsigned NOT NULL,
  `region_language` varchar(7) COLLATE utf8_unicode_ci NOT NULL,
  `region_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`region_id`,`region_language`),
  KEY `region_name` (`region_name`),
  KEY `country_id` (`country_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

-- --------------------------------------------------------

--
-- Table structure for table `tech_regions_positions`
--

CREATE TABLE IF NOT EXISTS `tech_regions_positions` (
  `region_id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `latitude_top` double(9,6) NOT NULL,
  `latitude_bottom` double(9,6) NOT NULL,
  `longitude_left` double(9,6) NOT NULL,
  `longitude_right` double(9,6) NOT NULL,
  PRIMARY KEY (`region_id`),
  KEY `region_GCS` (`latitude_top`,`latitude_bottom`,`longitude_left`,`longitude_right`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ;

 


Скажи миру - НЯ!

Неактивен

 

#27 15.11.2012 18:46:45

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

Почему добавлены ид стран в таблице городов - чтоб юзер мог искать по городам, а я ему могла предложить на выбор страну(-ы) в подсказках


Скажи миру - НЯ!

Неактивен

 

#28 15.11.2012 19:07:40

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5833

Re: Ускорит или замедлит?

Shopen написал:

vasya написал:

Explain показывает, что объединение идет с таблицы tech_regions_positions и дополнительное условие на `country_id` ухудшает план, приводя к лишней проверке. (Using where во втором плане)

Как это к лишней? )
Это же все равно что искать в базе Ивановых, но если среди них искать еще и Андреев - то новое условие ухудшит план )))


animegirl написал:

Значит убрать

Условие либо нужно либо нет, если результат не зависит от country_id - то зачем вообще это условие в запросе? Если country_id влияет на запрос - как вы его уберете, если оно необходимо для уточнения результата?

Я понял так, что нужны Андреи Ивановы, проживающие в Юрюписке. Причем заранее известно, что всех Ивановых в Юрюпинске зовут Андреями. Тогда мы можем решить задачу или проверкой фамилии у каждого жителя Юрюпинска (в этом случае проверка имени избыточна), или выбрать всех Ивановых Андреев и у каждого проверить место проживания.

Вопрос автора какой из методов быстрее. Ответ зависит от конкретных данных.

Неактивен

 

#29 16.11.2012 03:27:47

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

vasya написал:

animegirl написал:

Я ещё что подумала, есть смысл заменить

(25<=`tech_regions_positions`.`longitude_left` AND `tech_regions_positions`.`longitude_left`<=25)
на
(`tech_regions_positions`.`longitude_left` BETWEEN 25 AND 25)
?

Нет, это синонимы.

Если это синонимы, и вы говорите, что переделывать не стоит, я правильно понимаю, что если я бы заменила одно на другое, то мог бы не сработать индекс? Или есть другая причина?


Скажи миру - НЯ!

Неактивен

 

#30 16.11.2012 03:48:33

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5833

Re: Ускорит или замедлит?

Синонимы это значит без разницы, как писать.
Индекс не сработает целиком в случае если у вас будут не 25 и 25, а отличающиеся числа, например, 24 и 25. Это формы записи это не зависит.

Неактивен

 

#31 16.11.2012 03:52:00

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

Индексы не работают с знаками > <?


Скажи миру - НЯ!

Неактивен

 

#32 16.11.2012 04:14:58

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5833

Re: Ускорит или замедлит?

Заканчивают на них работу.
Или вы не внимательно прочитали FAQ №5, или авторы невнятно описали, или мы сейчас говорим о разных вещах.

Неактивен

 

#33 16.11.2012 04:17:56

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

Видимо акцентировала своё внимание на другом, но сейчас вспомнила данный момент в той теме sad
Но имеет смысл оставить, так как ведь может и попасть на =, хотя при координатах я в этом сомневаюсь sad


Скажи миру - НЯ!

Неактивен

 

#34 16.11.2012 04:31:44

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5833

Re: Ускорит или замедлит?

animegirl написал:

Но имеет смысл оставить, так как ведь может и попасть на =, хотя при координатах я в этом сомневаюсь sad

Зависит от количества таких запросов. Если их будет мало, то и смысла нет никакого. Ненужные индексы тоже плохо.

Неактивен

 

#35 16.11.2012 04:33:12

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

Такие запросы это основа проекта, он на геопривязке основан (


Скажи миру - НЯ!

Неактивен

 

#36 16.11.2012 16:57:48

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Ускорит или замедлит?

animegirl написал:

Такие запросы это основа проекта(

какие такие запросы, вот такие -

( `longitude_left`=25 OR `longitude_right`=25 ) AND ( `latitude_top`=25 OR `latitude_bottom`=25 )
?

Изначально мне казалось, что у вас будут в основном запросы определяющие некую область, а не линию (иначе зачем в запросе проверки на неравенство). Т.е. типа так -
( 0 <= `longitude_left`<= 25 OR 0 <= `longitude_right`<= 25 ) AND ( 0 <= `latitude_top`<= 25 OR 0 <= `latitude_bottom` <= 25 )


в этом и в любом подобном случае ваши индекс не будет использоваться, кроме первой координаты (top) и то не факт, зависит от реальных данных

Отредактированно Shopen (16.11.2012 16:58:09)

Неактивен

 

#37 16.11.2012 17:06:35

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

Запросы по координатам.
Их будет два типа
1. Поиск наложения одного прямоугольника на другой
2. Поиск точки в прямоугольнике


Скажи миру - НЯ!

Неактивен

 

#38 16.11.2012 17:09:53

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

А если их сделать каждый самостоятельным?
Я не до конца поняла, вот эту фразу "Заканчивают на них работу."
То есть он использует один из них а дальше нет, или же как только видит такой знак сравнения сразу перестаёт использовать их? Если первый вариант, тогда всё-таки выходит предложение выше по вынесению каждой координаты в свой индекс, имеет смысл?


Скажи миру - НЯ!

Неактивен

 

#39 16.11.2012 18:36:29

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5833

Re: Ускорит или замедлит?

animegirl написал:

Запросы по координатам.
Их будет два типа
1. Поиск наложения одного прямоугольника на другой
2. Поиск точки в прямоугольнике

Посмотрите в сторону пространственных индексов
http://dev.mysql.com/doc/refman/5.5/en/ … sions.html

Неактивен

 

#40 16.11.2012 18:40:43

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5833

Re: Ускорит или замедлит?

animegirl написал:

А если их сделать каждый самостоятельным?
Я не до конца поняла, вот эту фразу "Заканчивают на них работу."
То есть он использует один из них а дальше нет, или же как только видит такой знак сравнения сразу перестаёт использовать их? Если первый вариант, тогда всё-таки выходит предложение выше по вынесению каждой координаты в свой индекс, имеет смысл?

О чем вам Shopen с самого начала и говорил.
В случае составного индекса при операциях больше/меньше будет использована только первая часть индекса. В случае отдельных индексов MySQL хотя бы сможет выбрать наиболее селективный из них.

Неактивен

 

#41 17.11.2012 01:14:32

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

vasya написал:

animegirl написал:

Запросы по координатам.
Их будет два типа
1. Поиск наложения одного прямоугольника на другой
2. Поиск точки в прямоугольнике

Посмотрите в сторону пространственных индексов
http://dev.mysql.com/doc/refman/5.5/en/ … sions.html

У меня с английским тугова-то. Я не смогла найти вид записи в Пойнтах, поняла, что там 2 координаты, но можно ли их делать флоат? И как я их получу обратно, в каком виде? У вас нету в закромах хорошего мануала по данной тематике?


Скажи миру - НЯ!

Неактивен

 

#42 17.11.2012 01:35:41

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5833

Re: Ускорит или замедлит?

Поищите гугле. Например, http://lib.rus.ec/b/328368/read  Про качество ничего не скажу, не читал.

Неактивен

 

#43 17.11.2012 06:27:23

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

Спасибо, не поленилась, почитала, заодно не только о геометрии, но и много из остального, поняла, что коней на переправе не меняют, пускай это будет переделано в версии 2.0, а не на кануне сдачи первой версии )


Скажи миру - НЯ!

Неактивен

 

#44 18.11.2012 12:30:36

федя
Завсегдатай
Зарегистрирован: 14.11.2012
Сообщений: 33

Re: Ускорит или замедлит?

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 =>  (геокоординаты). Или вы желает подсказать пользователю список ЯЗЫКОВ ? smile

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)

Неактивен

 

#45 18.11.2012 12:54:23

федя
Завсегдатай
Зарегистрирован: 14.11.2012
Сообщений: 33

Re: Ускорит или замедлит?

Ну и наконец самое важное:

Какой бы не был быстрый MYSQL, какое бы вы количество индексов не построили намного производительнее будет
организация промежуточного слоя "кэширования данных" (с использованием memcache или иного механизма).

Те весь земной шарик делите на 10000 регионов и стройте  на прикладном уровне HASH:
    X-Y => LANG

При приходе нового запроса X1, Y1 обращаетесь к СУБД и вносите в HASH еще одну запись...

Таким образом определение LANG для 30% пользователей (к примеру из региона МОСКВА) у вас будет вообще без обращения к СУБД (мгновенно получать ответ RU).

ps.
Но это в версии 2.1 smile

Неактивен

 

#46 19.11.2012 17:13:57

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

федя написал:

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 =>  (геокоординаты). Или вы желает подсказать пользователю список ЯЗЫКОВ ? smile

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 края, надо найти, всё, что хоть как-то находится внутри, не только полное вхождение, но и частичное тоже.


Скажи миру - НЯ!

Неактивен

 

#47 19.11.2012 17:15:14

animegirl
Активист
Зарегистрирован: 28.07.2011
Сообщений: 288

Re: Ускорит или замедлит?

федя написал:

Ну и наконец самое важное:

Какой бы не был быстрый MYSQL, какое бы вы количество индексов не построили намного производительнее будет
организация промежуточного слоя "кэширования данных" (с использованием memcache или иного механизма).

Те весь земной шарик делите на 10000 регионов и стройте  на прикладном уровне HASH:
    X-Y => LANG

При приходе нового запроса X1, Y1 обращаетесь к СУБД и вносите в HASH еще одну запись...

Таким образом определение LANG для 30% пользователей (к примеру из региона МОСКВА) у вас будет вообще без обращения к СУБД (мгновенно получать ответ RU).

ps.
Но это в версии 2.1 smile

Пункт 3, логика запроса не в этом wink


Скажи миру - НЯ!

Неактивен

 

#48 19.11.2012 17:35:27

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Ускорит или замедлит?

ENUM по возможности использовать не следует. Не смотря на свои преимущества с точки зрения места хранения на диске, он не является переносимым (ибо это фича mysql, а не sql) и весьма непрост в понимании и поддержке, относительно других типов данных, конечно же. И по сети передаются конечно не индексы, а уже данные, так что выигрыша тут тоже не будет. Не советую

сглаживать гео-координаты до второго знака после запятой - это жесть smile

кстати, если мне память не изменяет, в случае 4 индексов, mysql не только сможет выбирать самый селективный, но и при определенных обстоятельствах мерджить их.

Неактивен

 

#49 19.11.2012 20:22:58

федя
Завсегдатай
Зарегистрирован: 14.11.2012
Сообщений: 33

Re: Ускорит или замедлит?

Shopen написал:

ENUM по возможности использовать не следует. Не смотря на свои преимущества с точки зрения места хранения на диске, он не является переносимым (ибо это фича mysql, а не sql) и весьма непрост в понимании и поддержке, относительно других типов данных, конечно же.

То что ENUM это фича MySQL это понятно... Про переносимость тоже понятно...
Но в данном разделе речь идет про оптимизацию именно МySQL.
ENUM в MySQL это один из самых простых и доступных методов оптимизации.
Более того если запустить какой-нить "родной оптимизатор" он вообще предложит вам 90% колонок в ENUM преобразовать smile

ps.
Есть кстати еще и SET-ы, тоже очень полезная вещь для людей пишущих  "горы IF/CASE внутри SQL".
Я то лично так вообще никогда так не делаю, так как намного проще HASH на перл-е написать smile


Shopen написал:

И по сети передаются конечно не индексы, а уже данные, так что выигрыша тут тоже не будет. Не советую

Речь идет не про "индексы которые передаются", а про то что:

Описание ENUM расположено в заголовке таблицы.
Клиент mysql может (должен) прочитать этог заголовок и запомнить
что AAA=1, BBB=2, ..... XXX=18
По сети могут  передаваться один байт на каждый ENUM
2 2 18 18 1 2
А клиент их расшифровывать и отображать...
Делают ли так все клиенты, я не знаю... Но это одна из главных ФИЧ

Shopen написал:

сглаживать гео-координаты до второго знака после запятой - это жесть smile

Ну да если имется задача автоматически определить, что к нам зашла единственная жительница Камеруна говорящая на языке БИКЬЯ, то и 40 знаков после запятой не хватит smile

1 место: Самый редкий разговорный язык на нашей планете - это язык бикья. На нем говорит лишь одна 87-летняя женщина из деревни на границе между Камеруном и Нигерией.

Неактивен

 

#50 19.11.2012 21:19:32

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Ускорит или замедлит?

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 км - это может оказаться другая страна, что уж говорить про город или улицу

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson