[MySQL] Неламерский вопрос

stat5327000

Есть таблица. Мне нужно вывести её полностью, отсоритрованую по одному из полей.
Выбирать её одним запросом не хочется, т.к. она большая. Поэтому выбираю её частями.
Причём в связи с особенностями вывода данных мне надо выбирать разные части в отсоритрованной таблице.
Единственный способ который я вижу это делать несколько запросов вида:
SELECT * FROM table ORDER BY fname ASC LIMIT i1, s1
где i1 и s1 это соотв. номер с которого мне нужно выбирать данные s1 - смещение.
Таких запросов надо сделать несколько, причём s1 - как правило одинаковые для всех запросов, а вот i1 существенно разные, причём результаты запросов гаранировано не пересекаются.
Вопрос: Как можно увеличить скорость для подобной задачи?
Группировка всех запросов в один при помощи UNION по моим ощущениям скорости не добавляет никак. Есть ли ещё способы как-то по другому это сделать?
Это был первый вопрос, и второй вопрос: Как влияет SQL_BIG_RESULT на выполнение запроса? Когда имеет смысл его использовать?
Ну и последний вопрос: может ли помочь в данной ситуации параметр max_seeks_for_key если я точно знаю что по моему полю, по которому я сортирую, есть индекс и больше определённого числа записей я выбирать из базы не буду подобными запросами? Т.е. точно могу опрделить max(s1) для всех запросов до их выполнения?

kruzer25

Мне нужно вывести её полностью, отсоритрованую по одному из полей.
Выбирать её одним запросом не хочется, т.к. она большая.
Что-то не понимаю я такую логику

sinet

Таких запросов надо сделать несколько, причём s1 - как правило одинаковые для всех запросов, а вот i1 существенно разные, причём результаты запросов гаранировано не пересекаются.
А как результаты для одного и того же смещения будут не пересекаться?
Ну и +1 к penartur`у.
упд. [телепат мод] Может тебя спасёт union all? [/телепат мод]

stat5327000

Понятно, в общем уточняю задачу: есть таблица, сост. из 3 полей - id, name, email. Мне нужно вывести все записи отсортированые по name, в виде таблицы html (в одной ячейке - одна запись но не по строчно, т.е. не в таком порядке:
1 2 3 4
5 6 7 8
9 10 11 12
а вот в таком:
1 4 7 10
2 5 8 11
3 6 9 12
Если таблица небольшая, то я могу сделать просто:
SELECT * FROM table ORDER BY name ASC;
Получить всю таблицу, перенумеровать индексы так чтобы обеспечить соотв. порядок вывода и радоваться жизни. Но тогда получается что количество памяти необходимой для этого линейно зависит от размеров таблицы что не есть гуд.
Например чтобы вывести таблицу из 500000 записей, Apache расходует около 270Mb оперативной памяти. Многовато правда? Я кстати сам не понимаю почему так много, т.к. это получается около 600 байт на одну запись, хотя одна запись занимает в среднем 25-30 байт.
Никто не скажет почему кстати? У меня Apache 1.3.31, PHP5 Mysql 5. Все под Виндой, PHP установлен как модуль Апача.
Ну вот, поэтому я хочу реализовать вывод так, чтобы читать таблицу кусками, скажем по 5000 записей.
А как результаты для одного и того же смещения будут не пересекаться?
Мне нужно получить всё таблицу, поэтому я запросы составляю так, чтобы в LIMIT i1, s1
не было одинаковых i1, и s1 выбраны так, чтобы получить всю таблицу (в конечном итоге) но несколькими запросами.
Я думаю теперь логика должны быть понятна.
P.S. А ещё меня добило то, что чтобы вывести ту таблицу на 500000 записей IE 6.0 понадобилось (!) 650 Mb памяти.

stat5327000

И ещё вопрос. На этот раз ламерский и я почти уверен что заню ответ, но всё же хочу спросить:
Я правильно понимаю, что когда я делаю запрос через функцию mysql_query, то результат лежит на сервере MySQL пока не закончится сессия или я не сделаю free_result?
Или другими словами, правильно ли то, что функции типа mysql_fetch_row просто получают одну строку с сервера, но на сам результат (данные) это никак не влияет? В смысле что они хранятся до конца сессии либо до free_result ?

pitrik2

P.S. А ещё меня добило то, что чтобы вывести ту таблицу на 500000 записей IE 6.0 понадобилось (!) 650 Mb памяти.
ну это вполне нормально
а зачем тебе именно ВСЕ данные нужно вытягивать с БД?
ты явно что-то делаешь не так

stat5327000

Да, я сам понимаю что это неразумно и сам бы так никода не делал
Просто другу хочу помочь тестовую задачку решить. А там такое условие - всю таблицу надо вывести.

stat5327000

Глупый был вопрос.

korsar0156

CREATE TEMPORARY TABLE tmp
SELECT id FROM table ORDER BY name ASC;
SELECT table.id, name, email FROM tmp LEFT JOIN table USING(id) LIMIT start, count;
если по name есть индекс то скорее всего и без временной таблицы тормозить не будет
(то есть просто SELECT * FROM table LIMIT ...)
PS я предполагаю, что уж по id индекс точно есть.

qsk78

Если это конкретно MySQL, то может сделать так?

SET @i=0;
SELECT c.id, c.name, c.email FROM (
SELECT id, name, email, @i:=(@i mod 4) + 1 AS counter FROM table ORDER BY name) AS c
ORDER BY c.counter;

А если будет плохо работать на большой таблице, то открыть курсор и делать FETCH.

stat5327000

Всем спасибо! На самом деле я тут немного сламерил. При моём размере таблицы всё ж правильней оказалось делать один SELECT, а потом пользоваться замечательной функцией mysql_data_seek, т.к. основной расход памяти приходится всё таки на php и именно там важно не делать больших массивов.
Оставить комментарий
Имя или ник:
Комментарий: