Mysql на стороне сервера пейджинг, сортировка - PullRequest
0 голосов
/ 07 ноября 2018

Здравствуйте, у меня есть одна таблица в базе данных, которая содержит несколько столбцов, более 20 и содержит много записей о 2 миллионах

Таблица имеет один первичный ключ: Col1, и это также индекс для моей таблицы. , По некоторым причинам тип данных для этого столбца - varchar (200).

Я реализую пейджинг, сортировку и последующие операции на стороне сервера (фильтрация)

У меня проблема с производительностью, вот моя процедура

DELIMITER $$

CREATE DEFINER=`master`@`%` PROCEDURE `spGetData`(
    IN  DisplayStart int ,
    IN  SortCol int ,
    IN  SortDir nvarchar(10),
    IN  Search  nvarchar(255)
)
BEGIN

        DECLARE FirstRec int;
        DECLARE LastRec int;

        SET FirstRec = DisplayStart;

            select 
               col1,col2,col3,col4,col6,col7,col8,col9,col10,col11
               col12,col13,col14,col15,col16,col17,col18,col19,col20
               col21,
                ( select count(*) from myTable) as filtered

            from myTable



order by
case When (@SortCol = 0 and @SortDir = 'asc')  then col1 end asc ,
case When (@SortCol = 0 and @SortDir = 'desc') then col1 end desc ,

case When (@SortCol = 1 and @SortDir = 'asc')  then col2 end asc ,
case When (@SortCol = 1 and @SortDir = 'desc') then col2 end desc ,

case When (@SortCol = 2 and @SortDir = 'asc')  then col3 end asc ,
case When (@SortCol = 2 and @SortDir = 'desc') then col3 end desc ,

case When (@SortCol = 3 and @SortDir = 'asc')  then col4 end asc ,
case When (@SortCol = 3 and @SortDir = 'desc') then col4 end desc ,

case When (@SortCol = 4 and @SortDir = 'asc')  then col5 end asc ,
case When (@SortCol = 4 and @SortDir = 'desc') then col5 end desc ,

case When (@SortCol = 5 and @SortDir = 'asc')  then col6 end asc ,
case When (@SortCol = 5 and @SortDir = 'desc') then col6 end desc ,

case When (@SortCol = 6 and @SortDir = 'asc')  then col7 end asc ,
case When (@SortCol = 6 and @SortDir = 'desc') then col7 end desc ,

case When (@SortCol = 7 and @SortDir = 'asc')  then col8 end asc ,
case When (@SortCol = 7 and @SortDir = 'desc') then col8 end desc ,

case When (@SortCol = 8 and @SortDir = 'asc')  then col9 end asc ,
case When (@SortCol = 8 and @SortDir = 'desc') then col9 end desc ,

case When (@SortCol = 9 and @SortDir = 'asc')  then col10 end asc ,
case When (@SortCol = 9 and @SortDir = 'desc') then col10 end desc ,

case When (@SortCol = 10 and @SortDir = 'asc')  then col11 end asc ,
case When (@SortCol = 10 and @SortDir = 'desc') then col11 end desc ,

case When (@SortCol = 11 and @SortDir = 'asc')  then col12 end asc ,
case When (@SortCol = 11 and @SortDir = 'desc') then col12 end desc ,

case When (@SortCol = 12 and @SortDir = 'asc')  then col13 end asc ,
case When (@SortCol = 12 and @SortDir = 'desc') then col13 end desc ,

case When (@SortCol = 13 and @SortDir = 'asc')  then col14 end asc ,
case When (@SortCol = 13 and @SortDir = 'desc') then col14 end desc ,

case When (@SortCol = 14 and @SortDir = 'asc')  then col15 end asc ,
case When (@SortCol = 14 and @SortDir = 'desc') then col15 end desc ,

case When (@SortCol = 15 and @SortDir = 'asc')  then col16 end asc ,
case When (@SortCol = 15 and @SortDir = 'desc') then col16 end desc ,

case When (@SortCol = 16 and @SortDir = 'asc')  then col17 end asc ,
case When (@SortCol = 16 and @SortDir = 'desc') then col17 end desc ,

case When (@SortCol = 17 and @SortDir = 'asc')  then col18 end asc ,
case When (@SortCol = 17 and @SortDir = 'desc') then col18 end desc ,

case When (@SortCol = 18 and @SortDir = 'asc')  then col19 end asc ,
case When (@SortCol = 18 and @SortDir = 'desc') then col19 end desc ,

case When (@SortCol = 19 and @SortDir = 'asc')  then col20 end asc ,
case When (@SortCol = 19 and @SortDir = 'desc') then col20 end desc ,

case When (@SortCol = 20 and @SortDir = 'asc')  then col21 end asc ,
case When (@SortCol = 20 and @SortDir = 'desc') then col21 end desc ,


                limit FirstRec,10;

    END

Запрос очень медленный и вызывает проблему с размером буфера. Если я уберу заказ по предложению, он станет очень быстрым.

Так что мои вопросы

1- Как мне улучшить этот запрос и сделать так, чтобы сортировка по миллионам строк выполнялась быстро?

2 - Позже я буду применять фильтрацию с использованием условия where для нескольких столбцов. Как избежать проблем с производительностью?

1 Ответ

0 голосов
/ 08 ноября 2018
  • ORDER BY должен быть создан (concat, prepare, execute, освобождает) вместо того огромного выражения, которое не может использовать какой-либо индекс.
  • Возможно, но не реально добавить INDEX(col0), INDEX(col1), ..., чтобы подготовленное утверждение было быстрым во всех 21 случаях. Выберите важные и не предоставляйте остальное конечному пользователю.
  • Не используйте OFFSET для разбивки на страницы ; вместо этого «запомни, где ты остановился».
  • Где фильтрация? Это может помешать советам, которые я вам уже дал.
  • VARCHAR(200) обычно неразумно для PRIMARY KEY.
  • Сможет ли пользователь указать сортировку по двум столбцам? Фильтрация по диапазонам дат? Другие вещи? (Пожалуйста, укажите реальные SHOW CREATE TABLE, если вы хотите получить более подробную информацию.)
  • Вы "нормализовали" какие-либо столбцы? То есть перемещать большие, часто повторяющиеся значения в другие таблицы.
...