LINUX.ORG.RU

Оптимизация таблицы содержащей около 2 миллионов записей


1

3

Имеется таблица содержащая около 2 миллионов записей. Выборка из начала (LIMIT 0, 30) происходит довольно быстро, однако чем больше OFFSET тем медленнее выборка. Выборка LIMIT 1782420, 30 не завершилась даже за 5 минут. Даже несколько минут это не дело т.к. может быть большое количество пользователей работающих с веб приложением одновременно и запрашивающих страницы с большими номерами. Никакие индексы не помогают (снижают время доступа к первым страницам но не к последним). Fixed (ROW_FORMAT) не помог. Как это можно оптимизировать? Неужели современная вычислительная техника не способна на создание приложения просто показывающего пользователям такой объём информации?


Ответ на: комментарий от pi11

Вобщем проблему решил так:

CREATE TABLE `videos_index` (
  `id` bigint(20) unsigned NOT NULL,
  `created_on` datetime NOT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `created_on_id` (`created_on`,`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED;

INSERT INTO videos_index SELECT id, created_on FROM videos;
tyler19
() автор топика
Ответ на: комментарий от Deleted

where v.id>xxxx /*тут айдишник какой нить 1505000 записи после которой можно 30 отсчитать*/

Уже советовали, ненадёжно. Что будет если придётся удалить некоторые записи, в принципе уже сейчас есть пробелы.

tyler19
() автор топика
Ответ на: комментарий от tyler19

select id from videos_index order by created_on desc, id desc limit 1050050, 30 в MySQL выполняется меньше секунды.

select * from videos where id in (ids from previous query) также выполняется очень быстро.

А вот select videos.* from videos_index left join videos on videos_index.id = videos.id order by videos_index.created_on desc, videos_index.id desc limit 1050050, 30 подвисает почему то надолго хотя по идее результат аналогичен двум предыдущим queries.

tyler19
() автор топика
Ответ на: комментарий от tyler19

select * from videos where id in (ids from previous query) также выполняется очень быстро.

Ну так и делают. По первичному ключу всегда быстрее. Часто дешевле сделать 100 запросов по ключу чем один тяжелый.

pi11 ★★★★★
()
Ответ на: комментарий от Anoxemian

а уж enum(varchar,varchar) вместо enum(int,int), вообще не от мира сего. и даже не enum должен быть, а тупо int.

Разве не так в итоге получается: строковые значения хранятся в схеме таблицы, а в записях и индексах — UNSIGNED SMALLINT? В документации ENUM() вообще проходит как строковый тип.

ksa242
()
Ответ на: комментарий от tyler19

ничего не будет - запоминаешь последний айдишник на странице - следующая страница 20 айдишников больше запомненного, ты хоть тыщц после него удали будут показаны 1001 и тд

Deleted
()
Ответ на: комментарий от ksa242

У тебя там еще и индекс по этому полю, в общем, бесполезный. Распределение никакое, поле текстовое, но даже если бы и нет, то битмапов в MySQL не бывает и, видимо, не будет. А да, и поскольку оптимизатор в MySQL несколько индексов подключать не умеет (это все еще так, кстати?), то есть ненулевая вероятность, что этот будет только мешаться.

anonymous
()
Ответ на: комментарий от anonymous

У тебя там еще и индекс по этому полю, в общем, бесполезный.

У меня тут и базы такой нет.

Я имел в виду, что ENUM(VARCHAR, VARCHAR) от предложенных ENUM(INT, INT) и даже «тупо INT» на практике не отличается — в самой таблице и индексах (если таковые будут) в любом случае хранится INT.

оптимизатор в MySQL несколько индексов подключать не умеет

Index merge же.

ksa242
()

Делай навигацию вида вперед-назад, как в гугле, при чтении очередной страницы запоминай последний id (или по какому там полю у тебя сортировка) и для следующей страницы бери записи у которых этот id больше. Это единственный способ организации корретного и быстрого пейджинга. Естественно можешь делать вперед-назад страниц на десять, просто вычитывая больше данных. Это всё, что может реально понадобиться пользователю в случае такой идиотской выборки. А прыгать ровно на 163892-ю страницу и никак иначе — никому не придет в голову в здравом смысле.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)
Ответ на: комментарий от Legioner

Это единственный способ организации корретного и быстрого пейджинга

Уже реализовал быстрый способ перехода на произвольную страницу (см. выше). Так что данное утверждение некорректно.

tyler19
() автор топика
Ответ на: комментарий от RR

http://www.percona.com/files/presentations/ppc2009/PPC2009_mysql_pagination.pdf

Какой то индус (фамилия позабавила) написал чепуху, я и без него знаю прекрасно что если убрать большие оффсеты всё будет летать. Нахера тогда миллионы записей в базе? Снести все кроме первых 50 и проблема решена...

tyler19
() автор топика
Ответ на: комментарий от tyler19

Ты либо дурак, либо статью не читал. /thread

RR
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.