Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> MySQL - индексы - ORDER BY, И снова он, ман не помогает 
:(
    Опции темы
-=Ustas=-
Дата 19.9.2006, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Мое почтение!
Уже бесить начинает, либо просто отдохнуть надо! Дело вот в чем: В книге написано что инедксы ставятся на те поля, которые учавсвуют в WHERE условии или в ORDER BY выражении. Есть такая таблица (обрисую образно, на самом деле там таблица гораздо больше и не одна, в запросе учавствует, но этот пример за образец прокатит):
Код

DROP TABLE IF EXISTS `category`;
CREATE TABLE `category` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(50) collate cp1251_bin NOT NULL default '',
  `title` varchar(255) collate cp1251_bin NOT NULL default '',
  `created` int(10) NOT NULL default '0',
  `modified` int(10) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `name` (`name`),
  KEY `created` (`created`),
  KEY `modified` (`modified`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_bin;

В ней более 50 000 записей. Цифра не значительная, т.к. в постгрисе пашет на ура. Далее... делабюю запрос:
Код

SELECT * FROM `category` ORDER BY `created`

Ноль реакции, EXPLAIN пишет что кеи не юзаются и using filesort, т.е. понятно что перебирает всю таблицу. 
Делаю такой запрос:
Код

SELECT * FROM `category` WHERE `created` > 0 ORDER BY `created` 

`created` - это int - unix_timestamp, ясно что он никогда 0 равняться не будет. Кей начинает быть заюзаным, EXPLAIN в extra показывает using where, т.е. применение индексу пошло. И выполняется моментально (ну как и должно в принципе быть).
Так вот я что-то вообще не пойму эту систему, что надо делать чтоб желаемые индекированые поля были использованы в запросе? Это же не выход, добавлять голимые условия в WHERE !!!
Плз, обяъсните, или ткните носом. 

P.S. В мане читал, и читал из этой темы http://forum.vingrad.ru/index.php?showtopi...st&p=828643 но так нифига и не понял  smile  Блин....


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
muzer
Дата 20.9.2006, 01:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Вы упоминули, что в запросе участвует не одна таблица, это важно. Покажите запрос целиком.
Дело в том, что при джойне нескольких таблиц использовать индекс для сортировки уже сложнее, и он его начинает использовать только(?), если уже использует его же для WHERE (типа а почему бы не применить заодно для ORDER BY) и то не всегда (думаю, зависит от порядка джойна таблиц).

А описанный пример вообще должен в обоих случаях использовать индекс. Если не хочет - можно ему сказать после имени таблицы: FORCE INDEX (имя_индекса). 

Это сообщение отредактировал(а) muzer - 20.9.2006, 01:35
PM WWW   Вверх
-=Ustas=-
Дата 20.9.2006, 08:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Цитата(muzer @  20.9.2006,  01:34 Найти цитируемый пост)
А описанный пример вообще должен в обоих случаях использовать индекс.

Я тоже так думал...но...

Цитата(muzer @  20.9.2006,  01:34 Найти цитируемый пост)
Вы упоминули, что в запросе участвует не одна таблица, это важно. Покажите запрос целиком.

Вот табличка:
Код

CREATE TABLE `shop_product` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `pid` int(10) unsigned NOT NULL default '0',
  `tid` mediumint(6) unsigned NOT NULL default '0',
  `name` varchar(50) collate cp1251_bin NOT NULL default '',
  `title` varchar(255) collate cp1251_bin NOT NULL default '',
  `description` text collate cp1251_bin NOT NULL,
  `pages` int(10) unsigned NOT NULL default '0',
  `picture` varchar(60) collate cp1251_bin default NULL,
  `count` int(10) unsigned NOT NULL default '0',
  `rating` int(10) unsigned NOT NULL default '0',
  `fname` varchar(255) collate cp1251_bin NOT NULL default '',
  `fhash` varchar(255) collate cp1251_bin NOT NULL default '',
  `fid` mediumint(6) NOT NULL default '0',
  `year` int(10) unsigned default NULL,
  `price` float default '0',
  `sort` int(10) NOT NULL default '0',
  `letter` char(1) collate cp1251_bin NOT NULL default '',
  `active` enum('Y','N') collate cp1251_bin NOT NULL default 'N',
  `created` int(10) NOT NULL default '0',
  `modified` int(10) NOT NULL default '0',
  `comments` text collate cp1251_bin NOT NULL,
  `content` text collate cp1251_bin NOT NULL,
  `about` text collate cp1251_bin NOT NULL,
  `cuser` int(10) NOT NULL default '1',
  `muser` int(10) NOT NULL default '1',
  `last` int(10) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `pid` (`pid`),
  KEY `tid` (`tid`),
  KEY `count` (`count`),
  KEY `rating` (`rating`),
  KEY `fid` (`fid`),
  KEY `sort` (`sort`),
  KEY `letter` (`letter`),
  KEY `last` (`last`),
  KEY `created` (`created`),
  FULLTEXT KEY `title` (`title`),
  FULLTEXT KEY `description` (`description`),
  FULLTEXT KEY `comments` (`comments`),
  FULLTEXT KEY `content` (`content`),
  FULLTEXT KEY `about` (`about`),
  FULLTEXT KEY `all` (`title`,`description`,`content`,`about`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_bin;

Вот собсна сам запрос:
Код

SELECT 
    p.`id`, 
    p.`title`, 
    p.`active`, 
    p.`created`, 
    c.`id` AS `catID`, 
    c.`title` AS `catTitle` 
FROM 
    shop_product AS `p` 
INNER JOIN 
    shop_category AS `c` 
ON 
    p.`pid` = c.`id` 
WHERE 
    p.`active` = 'Y' 
ORDER BY 
    p.`created` 
DESC 
LIMIT 7

Выполняется где-то секунд 30. Вот результаты EXPLAIN:
Код

id  select_type  table  type  possible_keys  key  key_len   ref             rows   Extra  
1   SIMPLE          c   ALL     PRIMARY     NULL    NULL    NULL            225    Using temporary; Using filesort 
1   SIMPLE          p   ref     pid         pid     4       naukashop.c.id  145    Using where 



--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
Bikutoru
Дата 20.9.2006, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Увлекающийся
**


Профиль
Группа: Участник
Сообщений: 522
Регистрация: 24.5.2005
Где: Москва

Репутация: 1
Всего: 22



Немного не в тему, но все же:
unix_timestamp - это же неотрицательное число. Может тогда следует объявить и само поле не
Код

 `created` int(10) NOT NULL default '0',

а как 
Код

 `created` int(10) UNSIGNED NOT NULL default '0',


И такой вопрос: а чем именно обусловлен выбор int + unix_timestamp. Как я понял (из таблиц) у нас есть категории и продукты с датами создания и модификации. Мне кажется, что здесь гораздо лучше использовать тип TIMESTAMP, который обладает возможностью автоматического обновления своего значения.
http://dev.mysql.com/doc/refman/5.0/en/timestamp-4-1.html

Добавлено @ 11:21 
Пока искал информацию о timestamp'е нашел такую вещь
http://dev.mysql.com/doc/refman/5.0/en/datetime.html
(см. сообщение в комментариях)


--------------------
Человек, словно в зеркале мир — многолик, 
Он ничтожен — и он же безмерно велик!
Омар Хайям
PM   Вверх
muzer
Дата 20.9.2006, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Цитата(-=Ustas=- @  20.9.2006,  09:12 Найти цитируемый пост)
Я тоже так думал...но...

Что "но"? Не вижу ни одного опровержения, посмотрите explain'ы к тем запросам, которые у вас в первом примере, увидите сами.

-=Ustas=-, а какой индекс он должен по-вашему использовать? smile 
Логично ведь, что сначала он выбирает категории, потом все товары из выбранных категорий, затем отбирает только активные, затем сортирует. Можно попробовать его заставить сначала товары отбирать, т.е. STRAIGHT_JOIN после SELECT написать и оставить порядок таблиц такой же. Но я всё равно не уверен, что он начнёт индекс использовать..
PM WWW   Вверх
-=Ustas=-
Дата 20.9.2006, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Цитата(muzer @  20.9.2006,  11:40 Найти цитируемый пост)
Что "но"? Не вижу ни одного опровержения, посмотрите explain'ы к тем запросам, которые у вас в первом примере, увидите сами.

Я же написал еще в первом посте результаты EXPLAIN.
Цитата(Bikutoru @  20.9.2006,  11:19 Найти цитируемый пост)
лучше использовать тип TIMESTAMP, который обладает возможностью автоматического обновления своего значения.

Нет, я привык с INT  работать.

Вечером буду пробовать запросы переписывать.


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
muzer
Дата 20.9.2006, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Цитата(-=Ustas=- @  20.9.2006,  13:50 Найти цитируемый пост)
Я же написал еще в первом посте результаты EXPLAIN.

У меня в базах результаты explain'ов для аналогичных вашим запросов получаются логичные, с использованием индекса. Попробуйте написать FORCE INDEX.
PM WWW   Вверх
-=Ustas=-
Дата 20.9.2006, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Цитата(muzer @  20.9.2006,  18:19 Найти цитируемый пост)
У меня в базах результаты explain'ов для аналогичных вашим запросов получаются логичные, с использованием индекса. Попробуйте написать FORCE INDEX. 

Странно, а версия мускула какая?


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
Sardar
Дата 20.9.2006, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 1
Всего: 317



Цитата(-=Ustas=- @  19.9.2006,  21:21 Найти цитируемый пост)
    
SELECT * FROM `category` ORDER BY `created`

Цитата(-=Ustas=- @  19.9.2006,  21:21 Найти цитируемый пост)
Ноль реакции, EXPLAIN пишет что кеи не юзаются и using filesort, т.е. понятно что перебирает всю таблицу. 
Делаю такой запрос:

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


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
muzer
Дата 20.9.2006, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Sardar, для убыстрения сортировки (индекс-то уже отсортирован). MySQL считает, что затратнее при выборке всех строк идти по индексу и seek'ать данные из файла данных, нежели сортировать их налету при выборке. Спорить с разработчиками mysql'я не берусь, но считаю, что зависит от конкретного случая, кол-ва данных и т.д.

-=Ustas=-, я понял в чём разница, я тестировал учитывая условия вашей задачи, а вы просто абстрактный пример, так вот, если LIMIT добавить, в который написать число меньшее раза в два чем кол-во строк в таблице, то индекс подхватывается без FORCE INDEX, иначе нет.. smile Поведение одинаковое наблюдаю на 4.1.11 и 5.0.22.

PM WWW   Вверх
-=Ustas=-
Дата 20.9.2006, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Хм... счас попробовал под никсами на 5-ой версии мускула, все нормально и молниеностно выполняет. В EXPLAIN правильные ключи отображает smile 
Может быть что у меня на винде корявый мускул стоит?


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
-=Ustas=-
Дата 20.9.2006, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Цитата(muzer @  20.9.2006,  19:05 Найти цитируемый пост)
а вы просто абстрактный пример

Да, но суть в реальном запросе не меняется обсолютно.
Цитата(Sardar @  20.9.2006,  18:37 Найти цитируемый пост)
А зачем должен здесь использоваться индекс, если выбираються в прямом смысле все строки

Ну как зачем, для ORDER BY

Вот на винде, версия 4.1.6, 20 тыс записей, запрос:
Код

SELECT * FROM `category` ORDER BY `created` LIMIT 7

В EXPLAIN выдает filesort, сама выборка проходит около 30 сек.

Вот. Этот же самый запрос на никсе, версия 5.хх, 20 тыс записей, запрос абсолютно такой же - в EXPLAIN выдает key - created, время 0.00 sec

Что жу это получается, что гонки на винде?


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
Sardar
Дата 20.9.2006, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 1
Всего: 317



Цитата(-=Ustas=- @  20.9.2006,  18:55 Найти цитируемый пост)
Ну как зачем, для ORDER BY

Верно, видно я не выспался...  smile 
Запусти ANALYZE TABLE на таблице, достаточно что бы мускул "увидел" индексы.

Цитата(-=Ustas=- @  20.9.2006,  18:55 Найти цитируемый пост)
Вот. Этот же самый запрос на никсе, версия 5.хх, 20 тыс записей, запрос абсолютно такой же - в EXPLAIN выдает key - created, время 0.00 sec

Может таблица в кеше была, а под виндой чего сложного делалось параллельно...... да мало ли чего может быть smile
Запусти тест раз 50, по идее не должно быть таких разительных различий.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
-=Ustas=-
Дата 20.9.2006, 23:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Цитата(Sardar @  20.9.2006,  22:41 Найти цитируемый пост)
Запусти ANALYZE TABLE на таблице, достаточно что бы мускул "увидел" индексы.

Запустил smile :
Код

 Table                  | Op      | Msg_type | Msg_text
------------------------+---------+----------+-----------------------------
 database.shop_product | analyze | status   | Table is already up to date

EXPLAIN выдал тодже самое что и до этого.

Цитата(Sardar @  20.9.2006,  22:41 Найти цитируемый пост)
Может таблица в кеше была

Не думаю, сразу после перегрузки пробую.

Цитата(Sardar @  20.9.2006,  22:41 Найти цитируемый пост)
а под виндой чего сложного делалось параллельно...... да мало ли чего может быть 

Тоже мысль такая была, все процессы килял, оставлял только mysqld-nt.

Добавлено @ 23:14 
Наверное переснесу все, по-новой поставлю.

Добавлено @ 23:15 
Посмотрю, что получится smile


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
-=Ustas=-
Дата 27.9.2006, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Мужики, такой вопрос. Может чего-то не догоняю... Следуя мануалу, цитаты:
Код

Индекс может также использоваться и тогда, когда предложение ORDER BY не соответствует индексу в точности, если все неиспользуемые части индекса и все столбцы, не указанные в ORDER BY - константы в выражении WHERE. Следующие запросы будут использовать индекс, чтобы выполнить ORDER BY / GROUP BY.

[B]SELECT * FROM t1 ORDER BY key_part1,key_part2,...[/B]
SELECT * FROM t1 WHERE key_part1=constant ORDER BY key_part2
SELECT * FROM t1 WHERE key_part1=constant GROUP BY key_part2
SELECT * FROM t1 ORDER BY key_part1 DESC,key_part2 DESC
SELECT * FROM t1 WHERE key_part1=1 ORDER BY key_part1 DESC,key_part2 DESC

Код

Ниже приведены некоторые случаи, когда MySQL не может использовать индексы, чтобы выполнить ORDER BY (обратите внимание, что MySQL тем не менее будет использовать индексы, чтобы найти строки, соответствующие выражению WHERE):

   [B] * Сортировка ORDER BY делается по нескольким ключам: SELECT * FROM t1 ORDER BY key1,key2[/B]
    * Сортировка ORDER BY делается, при использовании непоследовательных частей ключа: SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2
    * Смешиваются ASC и DESC. SELECT * FROM t1 ORDER BY key_part1 DESC,key_part2 ASC
    * Для выборки строк и для сортировки ORDER BY используются разные ключи: SELECT * FROM t1 WHERE key2=constant ORDER BY key1
    * Связываются несколько таблиц, и столбцы, по которым делается сортировка ORDER BY, относятся не только к первой неконстантной (const) таблице,


Это что, противоречие?! И что здесь в этих примерах подразумавается под key и key_part?
Я сделал аналогично этому:
Код

Индекс может также использоваться и тогда, когда предложение ORDER BY не соответствует индексу в точности, если все неиспользуемые части индекса и все столбцы, не указанные в ORDER BY - константы в выражении WHERE. Следующие запросы будут использовать индекс, чтобы выполнить ORDER BY / GROUP BY.

SELECT * FROM t1 ORDER BY key_part1,key_part2,...
[B]SELECT * FROM t1 WHERE key_part1=constant ORDER BY key_part2[/B]


Т.е. :
Код

CREATE TABLE `test` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(50) collate cp1251_bin NOT NULL default '',
  `title` varchar(255) collate cp1251_bin NOT NULL default '',
  `pid` int(10) unsigned NOT NULL default '0',
  `active` enum('Y','N') collate cp1251_bin NOT NULL default 'N',
  `sort` int(10) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `pid` (`pid`),
  KEY `sort` (`sort`),
  KEY `active` (`active`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_bin;

Делаю запрос:
Код

EXPLAIN SELECT * FROM test WHERE pid = 5 ORDER BY sort DESC;

И он мне говорит что Using filesort. В чем дело, или я что-то не понимаю?
P.S. Не пинайте сильно, и по возможности, если я не прав, объясните в чем я не прав. Или я неправильно себе представляю работу индексов?!


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
sergejzr
Дата 27.9.2006, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 1
Всего: 360



В запросах используется всегда один индех на таблицу. Этому меня умная книжка научила. Если делаешь JOIN то индех считай уже ушёл на составление таблиц. Советуют пользоваться двойными индексами, вот только пока не разбирался, но положительных результатов пока не было...


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
-=Ustas=-
Дата 27.9.2006, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Цитата(sergejzr @  27.9.2006,  17:51 Найти цитируемый пост)
В запросах используется всегда один индех на таблицу.

Хм... странно вообще-то. Но индексы, поля котороых присутствуют в условии WHERE, ведь там он используется вместе?! Или я опять ошибаюсь....


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
skyboy
Дата 27.9.2006, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(-=Ustas=- @  27.9.2006,  18:32 Найти цитируемый пост)
Но индексы, поля котороых присутствуют в условии WHERE, ведь там он используется вместе?! Или я опять ошибаюсь.... 

в смысле? никто ж не говорит, что индексы могут быть только "однопольные" - индекс может распространяться на несколько полей. Но применяться будет только один индекс. и странного я не вижу: как можно несколько индексов одновременно использовать? я не представляю smile
PM MAIL   Вверх
-=Ustas=-
Дата 27.9.2006, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Цитата(skyboy @  27.9.2006,  19:50 Найти цитируемый пост)
как можно несколько индексов одновременно использовать? я не представляю smile

Хорошо. Допустим, банальный пример из выше-приведенной таблицы. Если использовать множественный индекс по правостороннему принципу (по-моему так правильно назыввается smile ), т.е.:
Код

CREATE INDEX `all` ON test(pid,active,sort);

То тогда все пучком, запрос, типа
Код

SELECT * FROM test WHERE pid = 5 AND active = 'Y' ORDER BY sort;

Выполняется ИДЕАЛЬНО, с использованием этих трех индексов, Using filesort нету, и правильно. Но... тогда что получается, если мне нужен другой запрос, типа:
Код

SELECT * FROM test WHERE sort > 0 AND active = 'Y' ORDER BY pid; /*Правосторонний порядок индекса уже нарушен*/

То я должен для этого запроса создавать отдельный множественный индекс??? Т.к. уже индекс all не используется на данный запрос. Неужели все-таки нужно создавать каждые индексы на какие-нить индивидуальные запросы? Тогда и места на диске не напасешься smile


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
skyboy
Дата 27.9.2006, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(-=Ustas=- @  27.9.2006,  19:21 Найти цитируемый пост)
Выполняется ИДЕАЛЬНО, с использованием этих трех индексов,

нету там трех индексов. ну, если принимать в расчет только 
Код

SELECT * FROM test WHERE pid = 5 AND active = 'Y' ORDER BY sort;

и не надо "на все случаи жизни". при нормализации по 5 НФ вообще можно обойтись только индексом на поле первичного ключа smile Только это уже слишком, даже в общем случае... 
PM MAIL   Вверх
-=Ustas=-
Дата 28.9.2006, 09:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Цитата(skyboy @  27.9.2006,  21:33 Найти цитируемый пост)
и не надо "на все случаи жизни". при нормализации по 5 НФ

Т.е.? 5 НФ?

Цитата(skyboy @  27.9.2006,  21:33 Найти цитируемый пост)
вообще можно обойтись только индексом на поле первичного ключа

Да ну, не думаю что это будет оптимально smile


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
skyboy
Дата 28.9.2006, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(-=Ustas=- @  28.9.2006,  08:10 Найти цитируемый пост)
Т.е.? 5 НФ?

может, я чего и придумал smile однако я именно так по пояснениям преподавателя представил себе 5 нормальную форму smile
PM MAIL   Вверх
Ignat
Дата 28.9.2006, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

Репутация: 21
Всего: 73



На практике применяются, обычно, первые три нормальные формы. Пятая все же крайне нормализованная smile


--------------------
Теперь при чем :P
PM   Вверх
skyboy
Дата 28.9.2006, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Ignat, зато и в самом деле - более одного индекса на таблицу понадобиться просто не может smile
PM MAIL   Вверх
-=Ustas=-
Дата 28.9.2006, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Цитата(Ignat @  28.9.2006,  16:34 Найти цитируемый пост)
На практике применяются, обычно, первые три нормальные формы. Пятая все же крайне нормализованная

Какие еще формы? Пятая, третья.... Что то я вас, ребята, не понимаю smile
Цитата(skyboy @  28.9.2006,  16:53 Найти цитируемый пост)
более одного индекса на таблицу понадобиться просто не может

Дык, а если у таблицы связей много...

Добавлено @ 18:45 
Такс, пошел домой книгу изучать.... Хотя главы про индексы уже перечитывал несколько раз.


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
Ignat
Дата 28.9.2006, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

Репутация: 21
Всего: 73



Цитата(-=Ustas=- @  28.9.2006,  19:41 Найти цитируемый пост)
Дык, а если у таблицы связей много...

Значит таблица не находится в 5НФ smile


Цитата(-=Ustas=- @  28.9.2006,  19:41 Найти цитируемый пост)
Такс, пошел домой книгу изучать.... Хотя главы про индексы уже перечитывал несколько раз. 

Почитай лучше теорию реляционных БД ;)


--------------------
Теперь при чем :P
PM   Вверх
skyboy
Дата 28.9.2006, 18:58 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



PM MAIL   Вверх
muzer
Дата 28.9.2006, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Сколько у вас строк в таблице, что вы так боитесь filesort'а? smile
Когда объём данных переваливает за тот предел, при котором ORDER BY без индекса реально тормозит и исправить это разумным кол-вом индексов нельзя - нужно задуматься о создании избыточности данных, путём хранения в разных таблицах одного и того же в разном разрезе с разными индексами.

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

Считаю, нормальные формы нужно знать, чтобы уметь правильно мыслить при проектировании базы данных. Больше нормальные формы ни для чего не нужны, т.е. нельзя их в чистом виде использовать для построения бд.

Это сообщение отредактировал(а) muzer - 28.9.2006, 21:34
PM WWW   Вверх
skyboy
Дата 29.9.2006, 01:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(muzer @  28.9.2006,  20:34 Найти цитируемый пост)
Больше нормальные формы ни для чего не нужны, т.е. нельзя их в чистом виде использовать для построения бд.

что понимается под "чистым" видом? насколько часто необходимо идти "вразрез" с первой НФ(насколько я помню - это требование к "атомарности" единицы данных - поля)? 
PM MAIL   Вверх
muzer
Дата 29.9.2006, 01:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Цитата(skyboy @  29.9.2006,  02:04 Найти цитируемый пост)
что понимается под "чистым" видом?

Под чистым видом понимается приведение структуры БД строго к какой-либо нормальной форме.
На практике чаще всего есть частичное соответствие той или иной НФ, но т.к. определения НФ не подразумевают частичного соответствия, то я и говорю, что они служат только для развития мышления.

Цитата(skyboy @  29.9.2006,  02:04 Найти цитируемый пост)
насколько часто необходимо идти "вразрез" с первой НФ(насколько я помню - это требование к "атомарности" единицы данных - поля)?  

Хм..приходится. Когда нужно хранить список значений (являющихся праймари в другой таблице) переменной длины без необходимости использовать его в джойнах. Например, данные для загрузки в какую-либо программу. Хранить "вертикально" - очень затратно, большой объём получится, неповоротливая таблица.



Это сообщение отредактировал(а) muzer - 29.9.2006, 01:40
PM WWW   Вверх
skyboy
Дата 29.9.2006, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



muzer, не знаю, не знаю... одно дело - так хранить строки, другое дело - ключи... если по ним присоединять вообще ничего не надобно - то на кой их хранить? а если надо будет присоединять - то конструкция REGEXP не настолько быстра, чтоб заменить джойн по равенству...

Добавлено @ 08:38 
muzer, слушай, опиши структуру, при которой поребуется уйти от атомарности smile Ну, хоть кратко... Уж больно интересно
PM MAIL   Вверх
-=Ustas=-
Дата 29.9.2006, 10:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ustix IT Group
****


Профиль
Группа: Участник Клуба
Сообщений: 2222
Регистрация: 21.1.2005
Где: Краснодар

Репутация: 4
Всего: 69



Цитата(Ignat @  28.9.2006,  18:55 Найти цитируемый пост)
Почитай лучше теорию реляционных БД ;) 

Да уже читаю smile, во времена универа зубрил теорию - от зубов отскакивала, но на практике как-то больше смотрел в другую сторону smile
skyboy, спасибо за ссылку на статью.

Погрузился в чтение ))


--------------------
В искаженном мире все догмы одинаково произвольны, включая догму о произвольности догм.
-----
PM WWW ICQ Skype   Вверх
Grasshopper
Дата 23.10.2006, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 23.3.2006

Репутация: нет
Всего: 1



Цитата(muzer @ 29.9.2006,  06:38)
Цитата(skyboy @  29.9.2006,  02:04 Найти цитируемый пост)
насколько часто необходимо идти "вразрез" с первой НФ(насколько я помню - это требование к "атомарности" единицы данных - поля)?  

Хм..приходится. Когда нужно хранить список значений (являющихся праймари в другой таблице) переменной длины без необходимости использовать его в джойнах. Например, данные для загрузки в какую-либо программу. Хранить "вертикально" - очень затратно, большой объём получится, неповоротливая таблица.

при связи много-ко-многим создается отдельная таблица с двумя индексными полями - ключ от одной таблицы и ключ от другой. Другие решения представляются ГОРАЗДО более затратными по скорости
PM MAIL   Вверх
skyboy
Дата 23.10.2006, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Grasshopper @  23.10.2006,  16:26 Найти цитируемый пост)
Другие решения представляются ГОРАЗДО более затратными по скорости 

никогда не говори никогда. не бывает абсолютных лекарств. так же, как и НФ - не панацея и может быть ядом в некоторых случаях.
PM MAIL   Вверх
muzer
Дата 24.10.2006, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Grasshopper, при связи многие ко многим не всегда обязательно иметь возможность выбирать эти данные одним запросом и именно в базе. Но нужно иметь возможность быстро редктировать один из наборов.

skyboy, приведу пример похожий на реальный, но применив другую тематику, а то получится разглашение smile
представь, есть огромная база голосований: вопрос и несколько вариантов ответов. с одной стороны есть интерфейс их редактирования, с другой стороны есть движок, который на входе имеет некое условие, по которому отбирает вопрос, на выходе должен вернуть вопрос и все его ответы.
Делать селект из двух джойнов на каждый запрос - нет смысла, не живёт, нагрузка например неск сот запросов в секунду, вопросов 5 миллионов за всю историю, ответов соответсвенно раз в 10 больше (если в одной таблице хранить индексы, то это будет 5 млн х 50 млн = 500 млн...это не для MySQL'я). Понятно что ответы повторяются, их например 2 млн. Т.е. если загружать всё это по отдельности в память движка, в хэши и т.п., то решаются все поставленные задачи - мы можем быстро отвечать на запрос, мы можем быстро редактировать список ответов. Выбрать всё и сразу - такой задачи не стоит.
PM WWW   Вверх
skyboy
Дата 24.10.2006, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(muzer @  24.10.2006,  13:56 Найти цитируемый пост)
skyboy, приведу пример похожий на реальный, но применив другую тематику, а то получится разглашение 

smile и правда - не стОит 
Цитата(muzer @  24.10.2006,  13:56 Найти цитируемый пост)
Делать селект из двух джойнов на каждый запрос - нет смысла

не понял. 
если под  "каждым запросом" имелся  в виду отдельный вопрос, то мы же с самом начала выберем только один конкретный вопрос и "всего" не будет. 
если под "каждым запросом" имелся  в виду набор вопросов("анкета"), то внеся в базу структуру этой "анкеты" из логики работы обрабатывающей программы, мы получим возможность выбирать только то, что нам надо,опять же - без декартового произведения. 
может, я неверно понял, тогда растолкуй, если не сложно.
а может - после "неразглашения" и "смены тематики" пример утратил адекватность? smile
PM MAIL   Вверх
muzer
Дата 24.10.2006, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



может и утратил, но попробую..
Давай будем по этапам. Какая структура по нормализации должна быть?  Три таблицы, правильно?
T1. QuestionID | bla bla bla
T2. AnswerID | bla bla bla
T3. QuestionID | AnswerID

Сколько строк будет в таблице T3, если мы рассматриваем приведённый пример? 500 млн..

Выбрать нужно по какому-то bla-bla вопрос, и все его ответы. Т.е. SELECT .. FROM T1 INNER JOIN T3 USING(QuestionID) INNER JOIN T2 USING(AnswerID) WHERE T1.bla...

PM WWW   Вверх
skyboy
Дата 25.10.2006, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



а. теперь понял, что тебя смущает. только, во-первых, если речь о максимальном объеме таблицы, то можно разбить третью таблицу на несколько таблиц. Забыл, как этот процесс называется smile И потом, завтра на работе попробую сгенерировать пару милионов подобных строк(естественно, там ключ на оба поля наложить) и посмотреть, сколько же времеи займет подобная выборка.
Да, там можно ещё один столбец в третью таблицу, указывающий на порядок ответа в списке. Или на "вес" ответа. Или на признак "верности"(впрочем, нет - лучше это в четвертую таблицу). а если загонишь в одну строку типа "1, 2, 5, 29", то попробуй потом посчитай без REGEXP, какой ответ используется наиболее часто... Да, согласен с мыслью, что в зависимости от задачи может быть и рационально отступать от НФ, но, как на меня, пример не подтверждает это утверждение smile

Добавлено @ 00:14 
Цитата(skyboy @  24.10.2006,  23:09 Найти цитируемый пост)
Забыл, как этот процесс называется 

"репликация", что ли... черт, не буду больше пить пиво  smile 
PM MAIL   Вверх
muzer
Дата 25.10.2006, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Цитата(skyboy @  25.10.2006,  01:09 Найти цитируемый пост)
а если загонишь в одну строку типа "1, 2, 5, 29", то попробуй потом посчитай без REGEXP, какой ответ используется наиболее часто

А вот тут неточность smile нас никто не просит выдавать по этим данным какую-то статистику, нас просят за милисекунды ответить на запрос..

Сколько занимает времени подобная выборка вопрос не самый важный, самый важный вопрос - насколько быстрее будет работать схема не по НФ. Ответ - в десятки раз быстрее. А это значит, что требуется для работы ставить в десятки раз меньше серверов или сервера могут быть менее мощные.

Разбить таблицу на несколько можно, но это уже кластеризация, причём даже в текущем примере по непонятному признаку, а следовательно усложнение системы в разы.
(репликация - это некая схема объединения баз данных, когда, например, одна база зависит от другой (односторонняя репликация))
PM WWW   Вверх
skyboy
Дата 25.10.2006, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(muzer @  25.10.2006,  19:45 Найти цитируемый пост)
Ответ - в десятки раз быстрее.

не знаю, не зна... там - работа со строками, при НФ - работа с индексами по числам. Протестировать не получилось: только НФ-ый вариант. Выбор 3 строк из 236000 заняло горздо меньше секунды smile Время не замерял. Надо бы попробовать ещё ненормализованный вариант...
PM MAIL   Вверх
muzer
Дата 25.10.2006, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Где работа со строками? В коде на cи? Сделать SELECT *, распарсить, сложить в нужные структурки и готово.

Из 236 тысяч меньше секунды, ессно. А из 500 млн? даже из 100 млн.. И не забывай, что в несколько потоков.
PM WWW   Вверх
skyboy
Дата 25.10.2006, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



muzer, в смысле? склепай запрос, который при ненормализованном хранении соответсвий ответов и вопросов вытягивает список ответов для заданного вопроса. НЕ парсить строку "1, 2, 10, 30" на стороне клиента и динамическое формирование соотвествующимх запросов к таблице, а plain-SQL.

Добавлено @ 21:52 
пущай таблица вопросов: 
questions
idquestion(int autoinc)
title(varchar)
answers(varchar) - номера ответов через разделитель
answers
idanswer
title
________________
нормализованная форма:
questions
idquestion(int autoinc)
title(varchar)
answers
idanswer
title
questions_answers
idquestion
idanswer
________________
Для нормализованной формы:
Код

SELECT a.idanswer,a.title
FROM questions_answers qa
INNER JOIN answers a
ON a.idanswer=qa.idanswer
WHERE qa.idquestion= 23 /*просто число - красиво :)*/

Для ненормализованной ситуации(на REGEXP'ах):
Код

SELECT a.idanswer,a.title
FROM questions q
INNER JOIN answers a
ON q.answers REGEXP CONCAT("(^|,)",a.idanswer,"($|,)")
WHERE q.idquestion=23

Можно и без REGEXP'a, но лениво smile Может, сходу набросаешь?
______________
Как думаешь, что быстрее будет?
PM MAIL   Вверх
Ignat
Дата 26.10.2006, 10:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

Репутация: 21
Всего: 73



Цитата(skyboy @  25.10.2006,  22:43 Найти цитируемый пост)
Е парсить строку "1, 2, 10, 30" на стороне клиента и динамическое формирование соотвествующимх запросов к таблице, 

Притянуто за уши, но для примера. Имеются две таблицы:
В одной какие-либо события, допустим котировки акции, скажем пару миллионов записей. Во второй какое-то конечное число других сущностей, к примеру,  наименования бирж, на который торгуются акции, число ограничено десятком. Нам нужно выбрать строки с событиями, а также связать с таблицей бирж.
Первый вариант (таблицы находятся в нф): вводим таблицу для связей, при этом количество строк грубо = (количество котировок*AVG(количество бирж для каждой акции)), связываем по ключам min 2 джойна при выборке 2-х миллионов строк(!). Вариант кошерный, но не оправданный.

Вариант второй: список бирж через разделитель сохраняем в каждой строке
Выбираем все записи из таблицы бирж, храним в памяти. Выбираем котировки без джойнов. При анализе, в случае необходимости парсим строку и связываем с наименованиями, которые уже(!) находятся в памяти.

skyboy,  как думаешь, какой вариант быстрее?

Хоть это натянутый пример, но такое встречается чаще, чем хотелось бы.


--------------------
Теперь при чем :P
PM   Вверх
skyboy
Дата 26.10.2006, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Ignat, принято, хоть и притянуто. Только если "отталкиваться" от котировок. А если от бирж - посмотрим, что будет быстрее. И ещё вопрос: как ты, к примеру, отбросишь все котировки, которые не котируются на определенной бирже? или наоборот - котриуются? вообще, почти любое условие по отбору, которое в случае НФ уменьшало бы количество строк в разы, при не-НФ форме превратится в мегатонны головной боли smile

Добавлено @ 11:29 
Ignat, ха! ты из тонкого клиента одним движением сделал толстого! попробуй вернуться к тонкому клиенту и написать запрос типа моего(только у меня - REGEXP$ не лучшее решение), и посмотрим, кто - кого. Ведь маловероятно, чтоб набор котировок был конечным этапом - потом будет группировка вычисление кучи статистичесих параметров...
PM MAIL   Вверх
muzer
Дата 26.10.2006, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



skyboy, вот Игнат очень точно описал то, что пытался я smile У нас не стоит задачи вытягивать всё это одним запросом. Наша задача - давать как можно быстрее ответ на запрос к серверу. Как можно быстрее не получится, если мы будем использовать стурктуру по НФ. Но, ты совершенно справедливо отметил, что при не-НФ структуре выбрать всё одним запросом - это очень накладно. Но наша задача опять же в минимальной скорости ответа и возможности быстро редактировать список.

И как показывает практика, статистики намного меньше, чем множество всех возможных вариантов. Т.е. статистику имеет смысл хранить отдельно. В случае примера с голосованием, будет большое кол-во вопросов, на которые никогда не отвечали, будет большое кол-во ответов в некоторых вопросах, которые никогда не выбирали. Для них не имеет смысл хранить нули, лучше просто не хранить ничего.
PM WWW   Вверх
skyboy
Дата 26.10.2006, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(muzer @  26.10.2006,  11:45 Найти цитируемый пост)
Как можно быстрее не получится, если мы будем использовать стурктуру по НФ.

вернемся к вопросам-ответам. мне надо выбрать все ответы для вопроса №23.
я запуская запрос с двумя join'ами(если мне надо ещё и название вопроса) и получаю результат.
или
я запускаю запрос к базе, выдираю вопрос №23. парсю строку с описанием списка ответов и запихиваю номера в массив. потом обращаюсь к базе и получаю по номерам нужные мне ответы. так, что ли? я правильно понял?
PM MAIL   Вверх
Ignat
Дата 26.10.2006, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

Репутация: 21
Всего: 73



Цитата(skyboy @  26.10.2006,  17:51 Найти цитируемый пост)
потом обращаюсь к базе и получаю по номерам нужные мне ответы. так, что ли? я правильно понял? 

Да, но только не надо понимать буквально и на каждый ответ генерить запрос к БД. Достаточно собрать нужные ответы в конструкцию:
Код

... WHERE `answer` IN (1,5,7,9,56);

и выполнить один запрос.


--------------------
Теперь при чем :P
PM   Вверх
skyboy
Дата 26.10.2006, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Ignat, но парсинг строки происходит на стороне клиента! то есть данные надо прогнать в одну сторону, выделить под них буфер, записать, а потом - обратно. уверен, что будет быстрее?

Добавлено @ 18:44 
Ignat, значит, по-твоему, IN (подмножетсво) выполняется медленне INNER JOIN по первичному ключу? хм...  smile 
PM MAIL   Вверх
Ignat
Дата 26.10.2006, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

Репутация: 21
Всего: 73



Цитата(skyboy @  26.10.2006,  19:42 Найти цитируемый пост)
Ignat, значит, по-твоему, IN (подмножетсво) выполняется медленне INNER JOIN по первичному ключу? хм...

 smile 
Всё зависит от количества строк и использования индексов. Есть случаи оправданной "денормализации".


--------------------
Теперь при чем :P
PM   Вверх
skyboy
Дата 26.10.2006, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Ignat, конечно. пролистай страницу и убедись, что я не фанат. 
но в приведенном тобой примере количество бирж должно быть просто нереально малым, чтоб оправдать обработку на стороне клиента(2-3), если больше, то уже должно быть нехорошо...
И в примере muzerа тоже не все однозначно. Точнее, далеко не однозначно. 
Я ж не спорю с тем, что панацеи не бывает. Я просто желаю получить "жЫзненный" пример, когда денормализация - единственный выход, а НФ тормозят роботу с БД.

Добавлено @ 19:08 
Ignat, а IN разве будет быстрее UNION ALL?

Добавлено @ 19:09 
Цитата(skyboy @  26.10.2006,  18:05 Найти цитируемый пост)
Ignat, а IN разве будет быстрее UNION ALL? 

вопрос снимается. на самом деле, может быть быстрее, а может и нет. при UNION несколько сканирований, при IN(как мне кажется) не применяются ключи.

Добавлено @ 19:14 
Цитата(skyboy @  26.10.2006,  18:05 Найти цитируемый пост)
при IN(как мне кажется) не применяются ключи. 

ошибся. применяется. наверное, "разворачивается" в UNION.
PM MAIL   Вверх
Ignat
Дата 26.10.2006, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

Репутация: 21
Всего: 73



Цитата(skyboy @  26.10.2006,  20:05 Найти цитируемый пост)
но в приведенном тобой примере количество бирж должно быть просто нереально малым, чтоб оправдать обработку на стороне клиента(2-3), 

Совсем не 2-3, но, спешу заметить, бирж и так не много smile
На самом деле если число заведомо ограничено, до сотни строк в подчиненной таблице, то имеет смысл подумать о том, чтоб хранить её в памяти. Например, список регионов, областей, бирж, валют и т.д.

Я тоже не фанат, сам предпочитаю хранить в НФ, но повторюсь: таких случаев больше, чем хотелось бы.


--------------------
Теперь при чем :P
PM   Вверх
skyboy
Дата 26.10.2006, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Ignat @  26.10.2006,  18:18 Найти цитируемый пост)
то имеет смысл подумать о том, чтоб хранить её в памяти

а кеширование-то при чем? что мне мешает загрузить ответы, которые используются более, чем в 40% вопросов в память? что мне мешает записать все биржи у клиента и "делать JOIN" на стороне клиента, чтоб разгрузить базу? только каким боком использование и концепция кеша к НФ?
PM MAIL   Вверх
skyboy
Дата 27.10.2006, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



ещё одно "ЗА" для НФ: в MySQL при помощи group_concat можно "перейти" от НФ к неНФ, а обратное "преобразование на лету" невозможно smile

Добавлено @ 00:10 
надо бы в holy wars скинуть часть, а то разошлись тута слегка smile
PM MAIL   Вверх
muzer
Дата 27.10.2006, 00:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Как-то получилось много абстракций.
Давайте чётко определим, на какие вопросы хотим ответить.
Я вижу следующие:
1. Какой должна быть система, удовлетворяющая след критериям: минимальное время ответа, возможность изменять списки. Два варианта решения: 
а) сделать всё в базе по НФ с помощью трёх таблиц.
Минусы:
  •  при большом количестве данных промежуточная таблица становится сама по себе очень большой для mysql'я, растёт линейно
  •  внесение изменений требует редактирования промежуточной таблицы
  •  для получения ответа необходимо выполнить запрос с двумя джойнами между большими таблицами
Плюсы:
  •  fixed таблицы => лучше восстанавливаются, лучше фулл-сканятся
  •  не нужен умный сервер, загружающий все данные в память
б) сделать две таблицы, сделать промежуточный сервер, умеющий загружать необходимые данные в память
Минусы:
  •  трудоёмкость
Плюсы:
  •  при увеличении данных, таблицы растут медленнее промежуточной таблицы в пред варианте
  •  возможность моментального ответа на вопрос, ибо без джойнов
Ответа на вопрос нет, есть плюсы и минусы. Я считаю, что второй вариант предпочтительнее.

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

skyboy,
Жизненный пример: сеть контекстной рекламы на разных сайтах, типа Бегуна, гугл эдсенс и т.д. Есть страница какого-то вёбмастера, который установил у себя блок рекламы. Робот сети определил для этой страницы набор ключевых слов, по которым должна отбираться реклама. Задача: когда посетитель зашёл на сайт, нужно показать n объявлений. Чтобы найти объявления, нужно узнать ключевые слова для этой страницы. Что проще, выбрать одну строку со списком слов или выбрать десять строк по слову на строку? Сколько в инете страниц? Миллионы, миллиарды, сколько в среднем слов определяется на каждую страницу? Пусть десяток.. Где и как хранить миллионы помноженные на десяток слов? 
PM WWW   Вверх
skyboy
Дата 27.10.2006, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



muzer, надеюсь, твой пример - это не разглашение? :-|
Цитата(muzer @  26.10.2006,  23:30 Найти цитируемый пост)
Быстрее парсить и делать несколько селектов или довериться джойну?

не мог бы поподробнее описать, какой алгоритм ты имеешь в виду по "парсингом", чтоб я точно не обознался, и я протестирую.
Цитата(muzer @  26.10.2006,  23:30 Найти цитируемый пост)
Робот сети определил для этой страницы набор ключевых слов, по которым должна отбираться реклама.

как это выглядит? рекламный блок N связан со словами "world", "hello" и "happy", а страница M ассоциирована со словами "tree", "frieands" и "world" - потому и возникает соотвествие и реклама N отображается на сайте M? Т.е. определение пересечения подмножества? или четкое совпадение? если четкое совпадение требуется, могут ли слова в строке для блока и для сайта иметь разный порядок? 
Цитата(muzer @  26.10.2006,  23:30 Найти цитируемый пост)
Где и как хранить миллионы помноженные на десяток слов?  

хороший вопрос. положим, используем неНФ форму. Что хранится в неатомарном поле? списк индексов слов или(о, Боги!) сами слова? если сами слова, то на хранение требуется намного больше места, чем НФ-варианта. Впрочем, я так, с перепугу предположил. Не думаю, что так кто-нить делать будет при миллионе строк. Хотя... в среднем на такое поле из 10 слов 100 символов + 11 на идентификатор = 111 байт на строку или 111 * (количество сайтов == 1 000 000) = 100 Mb. Но не надо хранить слова. Но и группировка по словам такая, что проще застрелиться. И безопаснее для мозга.
Возьмем вариант, где в неатомарном поле хранятся индексы. 10 индексов по 10 символов + 9 символов-разделителей = 29 байт + 11 байт идентификатора = 40 байт на строку * (количество сайтов == 1 000 000) = 35 Mb. 
Примемся за НФ-вариант. на каждую строку: 11 +  11 = 22 байта, строк на сайт == 10, т.е. 220 байт; плюс отдельно хранятся идентификаторы сайтов(по 11 байт на сайт), где эти идентификаторы генерируются. Итого - 231 байт на сайт. 231 * (количество сайтов == 1 000 000) = 220 Mb. В самом деле, более, чем в два раза больше, чем для случая, когда записываем САМИ СЛОВА в таблицу. А ведь была ещё забыта таблица слов... 
Вот такая она, НФ-форма. 
PM MAIL   Вверх
muzer
Дата 27.10.2006, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Цитата(skyboy @  27.10.2006,  01:59 Найти цитируемый пост)
не мог бы поподробнее описать, какой алгоритм ты имеешь в виду по "парсингом", чтоб я точно не обознался, и я протестирую.


Цитата(skyboy @  27.10.2006,  01:59 Найти цитируемый пост)
хороший вопрос. положим, используем неНФ форму. Что хранится в неатомарном поле? списк индексов слов или(о, Боги!) сами слова?


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

Что я имел ввиду под парсингом:
SELECT word_id_list FROM table;  (разделитель в неатомарном поле - запятая)
SELECT word FROM dictionary WHERE word_id IN (word_id_list);
Это простейший пример. Только с помощью базу и простейшей обёртки. На деле же обе таблицы грузятся в память, ну а дальше всё то же самое только в синтаксисе языка.

По какому алгоритму идёт сравнение слов тут даже не важно, это другая задача.

Все необходимые для сравнения цифры ты, в общем-то, сам уже привёл smile
PM WWW   Вверх
skyboy
Дата 27.10.2006, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(muzer @  27.10.2006,  13:57 Найти цитируемый пост)
Все необходимые для сравнения цифры ты, в общем-то, сам уже привёл 

не все. объем - это не единственный параметр оценки. надо ещё скорость сравнить. только это будет зависеть от задачи. например, клиент - на удаленном компе, база - на сервере, имеющем IP. что мне лучше - передавать на клиента данные и ждать, пока он их распарсить и затребует другие данные, или самому распарсить? думаю, второе. вобщем, от канала очень сильно зависит. да и при работе PHP на том же сервере тоже может случиться, что быстрее будет СУБД парсить, чем работать с массивами в PHP. 
а убеждать меня не надо, сам знаю о вреде фанатизма. я просто ждал "универсального" примера, который сам по себе в отрыве от условностей вроде скорости передачи данных "обязывал" бы использовать неатомарные данные. но, наверное, такого примера быть не может. ну, и ладно smile

Добавлено @ 15:16 
ещё заметка: у неатомарного хранения большое ограничение: нельзя определить характеристики связей, если они есть. Например(для "вопросов - ответов") нельзя определить "вес" ответа и прочие характеристики(кроме порядка, пожалуй, потому как в неатомарном поле порядок как раз задан). Это просто, заметки на полях. smile
PM MAIL   Вверх
muzer
Дата 27.10.2006, 23:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



php не входит в список языков, которые я подразумевал smile
си, питон, ява на худой конец.. перл и пхп не для этих целей.

про разнесённые на диал-ап сервера мы тоже не говорим smile это каким надо быть извращенцем, чтобы поставить сервера одной сравнительно небольшой системы не на 100 Мбитный канал минимум)

про цифры - объём конечно не единственное. но помимо объёма уже недонократно обсуждали, два джойна делать.
PM WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.1297 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.