powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Прошу совета по оптимизации выборки из трех огромных таблиц
8 сообщений из 8, страница 1 из 1
Прошу совета по оптимизации выборки из трех огромных таблиц
    #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
Прошу совета по оптимизации выборки из трех огромных таблиц
    #33389006
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
InnoDB может быть быстрее в случае постоянных апдейтов таблиц, при выборке особой скорости появиться неоткуда...
Собственно, основная причина тормозов в том, что в результате объединения вы получаете 320 тысяч записей, и начинаете их сортировать без использования индекса, чтобы извлечь первые 5.
Рекомендую построить индекс по WareName, должно сделать запрос не столь мучительно долгим.
...
Рейтинг: 0 / 0
Прошу совета по оптимизации выборки из трех огромных таблиц
    #33390859
vick_ivanov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DocAlInnoDB может быть быстрее в случае постоянных апдейтов таблиц, при выборке особой скорости появиться неоткуда...
Да? А мне казалось, как раз наоборот, нет?
DocAlСобственно, основная причина тормозов в том, что в результате объединения вы получаете 320 тысяч записей, и начинаете их сортировать без использования индекса, чтобы извлечь первые 5.
Рекомендую построить индекс по WareName, должно сделать запрос не столь мучительно долгим.
Это понятно, индекс такой есть, непонятно только, как им пользоваться в моем случае - ведь объединение мне нужно по элементам классификатора, а не по товару.
...
Рейтинг: 0 / 0
Прошу совета по оптимизации выборки из трех огромных таблиц
    #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
Прошу совета по оптимизации выборки из трех огромных таблиц
    #33391229
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vick_ivanov DocAlInnoDB может быть быстрее в случае постоянных апдейтов таблиц, при выборке особой скорости появиться неоткуда...
Да? А мне казалось, как раз наоборот, нет?

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

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

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

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

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


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