|
|
|
| Здравствуйт!
Я перечитал множество тем на этом форуме связанных с постраничной навигацией.
Но там в основном приводится PHP код.
Меня интересует другое: Оптимизайия запроса к базе для целей постраничной навигации.
Запрос трёхтабличный, таблицы большие ~80М каждая.
Хотя логика пересечения таблиц не сложная, всё равно выборка выполняется довольно долго.
Хотелось хотя бы не делать двух отдельных запросов для выяснения :
1) общего числа строк отвечающих запрашиваемому условию и
2) вывода строк текущей страницы
Это как-то можно сделать?
Вот так не проходит:
SELECT id, count(*) FROM test LIMIT 10
|
Вот так тоже не проходит:
SELECT id, count(*) FROM test GROUP BY id LIMIT 10
|
| |
|
|
|
|
|
|
|
для: Eugene77
(22.02.2010 в 09:33)
| | Говорить что-то об оптимизации, не видя ни структуры таблиц, ни запроса - весьма самонадеянно.
Мануал по SELECT/LIMIT (SQL_CALC_FOUND_ROWS) Вы, по-моему, всё же не дочитали, хотя в Вашем конкретном случае, может это и на пользу. | |
|
|
|
|
|
|
|
для: Trianon
(22.02.2010 в 09:46)
| | Да, спасибо, точно: FOUND_ROWS() - остальное уже не вопрос. | |
|
|
|
|
|
|
|
для: Trianon
(22.02.2010 в 09:46)
| | >Мануал по SELECT/LIMIT (SQL_CALC_FOUND_ROWS)
Способ удобный но довольно медленный. Практика показывает что два запроса работают быстрее... Тем более что один из них, зачастую, можно сильно упростить. | |
|
|
|
|
|
|
|
для: Loki
(24.02.2010 в 12:02)
| | так я ж сразу приписал дисклеймер!
Но автор, как обычно, намек не воспринял. | |
|
|
|
|
|
|
|
для: Trianon
(24.02.2010 в 12:12)
| | Меня намёками не прймёшь, а матом здесь не разрешено...
Я уже про два запроса всё знаю - так и делал, но раз спросил, значит не подходит.
Вообще-то, не секрет почему не подходит: запрос занимает около 40 строк. | |
|
|
|
|
|
|
|
для: Eugene77
(25.02.2010 в 16:34)
| | Ну коль так - то лесом тогда идет соображение Loki - применительно к данному конкретному случаю.
Хотя, создавая запросы на 40 строк, Вы должны меня учить, а не я - Вас. | |
|
|
|
|
|
|
|
для: Trianon
(25.02.2010 в 16:46)
| | Учить "должен" тот, у кого больше знаний, профессионал.
Я в профессионалы ни под каким соусом не гожусь: ни стремления нет им стать, ни времени, ни опыта - так что вся надежда на вас.
Единственно почему я занимаюсь сейчас программированием, так это хочу доделать свой проект, который мне представляется важным. | |
|
|
|
|
|
|
|
для: Eugene77
(25.02.2010 в 16:34)
| | А пример запроса можно? Жуть как интересно... | |
|
|
|
|
|
|
|
для: Loki
(25.02.2010 в 17:18)
| | Ну вы тут прямо клуб какой-то устроили или избу читальню...
Хорошо, вот реальный пример:
SELECT SQL_CALC_FOUND_ROWS d1.s AS s, d1.w AS w1, d2.w AS w2,
s1.part AS part, s1.chapter as chapter,
s1.rime as rime1, s2.rime as rime2,
s1.sent_num as sent_num1, s2.sent_num as sent_num2,
s1.sent as sent1, s2.sent as sent2
FROM
my_db.pz_sentences AS s1,
my_db.pz_sentences AS s2,
(
SELECT num, s, w FROM
(SELECT DISTINCT `k` FROM my_db.all_ru_grammar WHERE i IN('заключительный') AND `use` != 'n') AS k1,
my_db.pz_words AS dd1 WHERE k1.k = dd1.w GROUP BY dd1.num
UNION
SELECT d3.num AS num, d3.s AS s, CONCAT_WS('|', d3.w, d4.w) AS w FROM
(SELECT `k`, `i` FROM my_db.all_ru_grammar WHERE i IN('домашний','работа') AND `use` != 'n' GROUP BY `k`) AS g3,
(SELECT `k`, `i` FROM my_db.all_ru_grammar WHERE i IN('домашний','работа') AND `use` != 'n' GROUP BY `k`) AS g4,
my_db.pz_words AS d3,
my_db.pz_words AS d4
WHERE
(g3.i = 'домашний' AND g4.i = 'работа') AND
g3.k = d3.w AND g4.k =d4.w AND
(d3.num = d4.num +1 OR d3.num = d4.num -1) AND
d3.s = d4.s
) AS d1,
(
SELECT num, s, w FROM
(SELECT DISTINCT `k` FROM my_db.all_ru_grammar WHERE i IN('сокровенный') AND `use` != 'n') AS k1,
my_db.pz_words AS dd1 WHERE k1.k = dd1.w GROUP BY dd1.num
UNION
SELECT d3.num AS num, d3.s AS s, CONCAT_WS('|', d3.w, d4.w) AS w FROM
(SELECT `k`, `i` FROM my_db.all_ru_grammar WHERE i IN('подвиг','рыцарь') AND `use` != 'n' GROUP BY `k`) AS g3,
(SELECT `k`, `i` FROM my_db.all_ru_grammar WHERE i IN('подвиг','рыцарь') AND `use` != 'n' GROUP BY `k`) AS g4,
my_db.pz_words AS d3,
my_db.pz_words AS d4
WHERE
(g3.i = 'подвиг' AND g4.i = 'рыцарь') AND
g3.k = d3.w AND g4.k =d4.w AND
(d3.num = d4.num +1 OR d3.num = d4.num -1) AND
d3.s = d4.s
) AS d2
WHERE
d1.s = s1.sent_num AND
d2.s = s2.sent_num AND
ABS(s1.rime - s2.rime) < 14 AND
ABS(s1.sent_num - s2.sent_num) < 42 AND
s1.chapter = s2.chapter AND
s1.part = s2.part
GROUP BY s1.sent_num
ORDER BY (ABS(s1.sent_num-s2.sent_num)+ABS(s1.rime-s2.rime))
|
Теперь мне осталось только выслушать от Хеопса, что такие длинные отрывки надо прикреплять, а не прямо печатать.
И он совершенно прав, потому что пользы от этой публикации абсолютно никакой, хотя код реально используется в моём проекте. Даже претерпел некоторую эволюцию. В начале он был заметно короче, но работал заметно дольше.
Разумеется, некоторые русские слова в него подставлены случайным образом (а на самом деле существует определённая закономерность (корреляция что-ли) в их появлении в данном запросе, но это длинная история). | |
|
|
|