Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Прошу совета по оптимизации выборки из трех огромных таблиц / 8 сообщений из 8, страница 1 из 1
20.11.2005, 19:56:42
    #33388878
vick_ivanov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу совета по оптимизации выборки из трех огромных таблиц
Господа, подскажите, плиз, с такими большими таблицами мне работать еще не приходилось (>300000-400000)
Пишу такой запрос для выборки из трех таблиц:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT w.Name AS name, w.WareID AS wareid, w.Price AS price
FROM Wares w
INNER JOIN ClassWares c ON w.WareID = c.WareID
INNER JOIN Classifier cl ON c.ClassID = cl.ClassID
WHERE (w.WareTypeId = '50')
AND (w.Barcode <> '-')
AND (w.Barcode IS NOT NULL)
AND (cl.ParentID = '2')
ORDER BY w.WareName limit  0 , 5 
wares - все товары (470 тыс.записей), здоровая таблица:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
CREATE TABLE `wares` (
  `WareID` int( 11 ) NOT NULL default '0',
  `WareTypeId` int( 11 ) NOT NULL default '0',
  `WareName` text,
  `NDS` int( 11 ) default NULL,
  `Status001` int( 11 ) default NULL,
  `Completing` varchar( 200 ) default NULL,
  `Weight` double( 15 , 3 ) default NULL,
  `W39F97` text,
  `Image` int( 11 ) default NULL,
  `ProductId` int( 11 ) default NULL,
  `Barcode` varchar( 200 ) default NULL,
  `Theme` varchar( 30 ) default NULL,
  `Country` varchar( 50 ) default NULL,
  `GTD` varchar( 30 ) default NULL,
  `BarCount` int( 11 ) default NULL,
  `Manufacturer` varchar( 250 ) default NULL,
  `UpdateColumn` bigint( 20 ) default NULL,
  `Key001` varchar( 100 ) default NULL,
  `Price` float( 9 , 2 ) default NULL,
  PRIMARY KEY  (`WareID`),
  KEY `waretypeid` (`WareTypeId`),
  KEY `barcode` (`Barcode`),
  KEY `theme` (`Theme`),
  FULLTEXT KEY `WareName` (`WareName`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

Classifier - каталог групп товара, 17000 записей
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE TABLE `classifier` (
  `ClassID` int( 11 ) NOT NULL default '0',
  `ClassName` varchar( 250 ) NOT NULL default '',
  `ClassShortName` varchar( 30 ) default NULL,
  `ParentID` int( 11 ) NOT NULL default '-1',
  `AllowableWareType` int( 11 ) NOT NULL default '-1',
  `Description` text,
  `Status` int( 11 ) NOT NULL default '0',
  `Stamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (`ClassID`),
  KEY `classshortname` (`ClassShortName`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

ClassWares - таблица принадлежности товара к группе классификатора
Код: plaintext
1.
2.
3.
4.
5.
CREATE TABLE `classwares` (
  `ClassID` int( 11 ) NOT NULL default '0',
  `WareID` int( 11 ) NOT NULL default '0',
  PRIMARY KEY  (`ClassID`,`WareID`),
  KEY `ClassWaresByWare` (`WareID`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

Цель моего запроса - сделать выборку значений по товарам из раздела классификатора, включая дочерние элементы каталога.
Такой запрос жутко тормозит. Explain показывает, что из первой таблицы берется огромная выборка, т.к. (w.WareTypeId = '50') - это почти все записи (320тыс.).
Может быть, стоит посмотреть в сторону InnoDB-таблиц?:) или вообще PostgreSQL? Или озадачится прикрутить к MS SQL базе, с которой я собственно и импортирую данные в MySQL?
Спасибо за советы:)
...
Рейтинг: 0 / 0
21.11.2005, 02:17:38
    #33389006
DocAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу совета по оптимизации выборки из трех огромных таблиц
InnoDB может быть быстрее в случае постоянных апдейтов таблиц, при выборке особой скорости появиться неоткуда...
Собственно, основная причина тормозов в том, что в результате объединения вы получаете 320 тысяч записей, и начинаете их сортировать без использования индекса, чтобы извлечь первые 5.
Рекомендую построить индекс по WareName, должно сделать запрос не столь мучительно долгим.
...
Рейтинг: 0 / 0
21.11.2005, 18:05:04
    #33390859
vick_ivanov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу совета по оптимизации выборки из трех огромных таблиц
DocAlInnoDB может быть быстрее в случае постоянных апдейтов таблиц, при выборке особой скорости появиться неоткуда...
Да? А мне казалось, как раз наоборот, нет?
DocAlСобственно, основная причина тормозов в том, что в результате объединения вы получаете 320 тысяч записей, и начинаете их сортировать без использования индекса, чтобы извлечь первые 5.
Рекомендую построить индекс по WareName, должно сделать запрос не столь мучительно долгим.
Это понятно, индекс такой есть, непонятно только, как им пользоваться в моем случае - ведь объединение мне нужно по элементам классификатора, а не по товару.
...
Рейтинг: 0 / 0
22.11.2005, 02:44:52
    #33391220
max(id)
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу совета по оптимизации выборки из трех огромных таблиц
DocAlСобственно, основная причина тормозов в том, что в результате объединения вы получаете 320 тысяч записей, и начинаете их сортировать без использования индекса, чтобы извлечь первые 5.А вот что говорится в документации :
MySQL ABЕсли LIMIT # используется с ORDER BY, MySQL закончит сортировку, как только найдет первые # строк, вместо того, чтобы сортировать всю таблицу.Так что мнение DocAl не является 100% причиной тормозов, хотя и содержит рациональное зерно...

Моё предложение будет таким: первым должен обрабатываться "классификатор" (думаю в нем не так много записей с ParentID = '2', хотя возможно это не так), а дальше уже соединяем результат с товарами через ClassWares. Выглядеть все это будет примерно так (к сожалению не могу проверить, поэтому результат не гарантирован ;-) ):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT w.Name AS name, w.WareID AS wareid, w.Price AS price
FROM Classifier cl 
     STRAIGHT_JOIN ClassWares c 
       ON c.ClassID = cl.ClassID and cl.ParentID = '2'
     STRAIGHT_JOIN  Wares w  
       ON w.WareID = c.WareID
WHERE (w.WareTypeId = '50')
AND (w.Barcode <> '-')
AND (w.Barcode IS NOT NULL)
ORDER BY w.WareName limit  5 
Рекомендую обратить внимание на то что вместо "limit 0,5" использован "limit 5"
и то что предикат cl.ParentID = '2' выполняется одним из первых, лучше бы самым первым. Да и индекс по этому полю не помешал бы ;-)
...
Рейтинг: 0 / 0
22.11.2005, 04:26:20
    #33391229
DocAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу совета по оптимизации выборки из трех огромных таблиц
vick_ivanov DocAlInnoDB может быть быстрее в случае постоянных апдейтов таблиц, при выборке особой скорости появиться неоткуда...
Да? А мне казалось, как раз наоборот, нет?

Вам казалось.
vick_ivanov
DocAlСобственно, основная причина тормозов в том, что в результате объединения вы получаете 320 тысяч записей, и начинаете их сортировать без использования индекса, чтобы извлечь первые 5.
Рекомендую построить индекс по WareName, должно сделать запрос не столь мучительно долгим.
Это понятно, индекс такой есть, непонятно только, как им пользоваться в моем случае - ведь объединение мне нужно по элементам классификатора, а не по товару.
[/quot]
В описании таблиц такого индекса нет. Полнотекстовый индекс для сортировки неприменим. (Кстати, реализован он только для MyISAM, так что если он используется -- переход на другой движок таблиц будет проблематичен.)
...
Рейтинг: 0 / 0
22.11.2005, 10:57:40
    #33391712
Валентин К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу совета по оптимизации выборки из трех огромных таблиц
Запрос афтара вопроса естественно отрабатывается так как описано, потому что inner join так и действует.

Во-первых не хватает индекса обычного на WareName, во вторых, почему обязательно связывать таблицы внутренним объединением ???

Может я не совсем понял задачу, но по моему можно связать обычным join.

Согласен с DocAl, InnoDB не решит проблему, на больших таблицах этот движок работает чуть медленее.
Переходить на PostgreSQL или на MS SQL не стоит, они работают медленее, но если вы не верите, закачайте туда и напишите запросы...

Покрутить еще раз запросы и задачу, перейти на 5.0 версию MySQL, в ней есть соединение индексов index_merge, что тоже ускорит отбор тяжелой таблицы..
...
Рейтинг: 0 / 0
22.11.2005, 11:22:05
    #33391801
maXmo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу совета по оптимизации выборки из трех огромных таблиц
Сортировка по полю типа text? Рекомендую перейти на пятый мускуль, там поле varchar можно делать длиной до 64кб (255 символов точно не хватает?). Значения типа text и blob ведут себя вроде как файлы.
------------------
- А как в Интеpнете pаботать? - Сначала нужно узнать, что вам нужно rtfm
...
Рейтинг: 0 / 0
30.11.2005, 12:12:42
    #33408032
vick_ivanov
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Прошу совета по оптимизации выборки из трех огромных таблиц
Сорри, сдавал другой проект, этим вопросом пока не занимался. Спасибо всем за ответы, буду сегодня экспериментировать:)
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Прошу совета по оптимизации выборки из трех огромных таблиц / 8 сообщений из 8, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]