powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Соседние записи таблицы после сортировки.
8 сообщений из 8, страница 1 из 1
Соседние записи таблицы после сортировки.
    #39482909
darknesmonk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ребята, помогите пожалуйста оптимизировать запрос.
есть таблица pictures

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
CREATE TABLE  `pictures` (
  `pid` int(11) NOT NULL AUTO_INCREMENT,
  `pdatetime` datetime DEFAULT NULL,
  `pname` text,
  `plink` varchar(100) DEFAULT NULL,
  `tlink` varchar(100) DEFAULT NULL,
  `pviewers` int(11) DEFAULT '0',
  `pwidth` smallint(4) DEFAULT NULL,
  `pheight` smallint(4) DEFAULT NULL,
  PRIMARY KEY (`pid`),
  KEY `pviewers` (`pviewers`,`pwidth`,`pheight`),
  KEY `plastviewip` (`plastviewip`),
  KEY `plike` (`plike`,`pdislike`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 COMMENT='Картинки' 



делаю выборку с сортировкой pwidth+pheight (ширина+высота рисунка)

Код: sql
1.
SELECT * FROM pictures ORDER BY  pwidth+pheight desc  



Выводится список всех рисунков по данной сортировки.

Потом делаю запрос для выбора одного рисунка по его PID
Код: sql
1.
 SELECT * FROM pictures WHERE pid=1234



задача: необходимо найти предыдущие и следующие элементы по данной сортировки относительно текущего PID
решил задачу топорно т.к. не так много рисунков, всего 4 000, и запрос занимает (0.0090сек)

нахожу его позицию $start через запрос:
Код: sql
1.
SELECT num FROM (SELECT @i:=@i+1 num,pid FROM pictures , (SELECT @i:=0) x   ORDER BY pwidth+pheight desc ) as t WHERE t.pid=1234 



после его смещаю на -5 и проверяю на отрицательное число
Код: php
1.
2.
3.
4.
 <?
 $start=$db->sres()-5;
    if($start<0) $start=0; 
?>



после делаю основной запрос:

Код: sql
1.
SELECT * FROM pictures ORDER BY  pwidth+pheight desc LIMIT $start,9



и получаю по середине данную картинку и 4 следующие и 4 предыдущие.
Как можно оптимизировать запрос?
...
Рейтинг: 0 / 0
Соседние записи таблицы после сортировки.
    #39483063
shplace
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот что получилось:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SELECT 
    pid, pwidth, pheight
FROM
(
    SELECT
        num, pid, pwidth, pheight
    FROM    
    ( 
        SELECT 
            @num := @num + 1 as num, pid, pwidth, pheight, 
            @mynum := @mynum + @delta as mynum,
            IF( pid = 3898, @delta := -1, @delta := @delta ) as delta
        FROM pictures p, ( select @num := 0, @mynum := 0, @delta := 1 ) z
        ORDER BY pwidth + pheight DESC
    ) gb
    ORDER BY mynum DESC
    LIMIT 9
) gb_trunc
ORDER BY num



Соответственно 3898 - заданный pid, 9 - заданный интервал
...
Рейтинг: 0 / 0
Соседние записи таблицы после сортировки.
    #39483084
shplace
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Но это не особо претендует на оптимизацию.

Просто засунул всё в один запрос.
...
Рейтинг: 0 / 0
Соседние записи таблицы после сортировки.
    #39483094
darknesmonk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
shplace, спасибо!

интересный вариант, но он дольше почти в 2 раза :( 0.0253 сек.
мои 2 запроса сейчас показывают 0.0063 + 0.0078 = 0.0141.
Может еще кто-то предложит?
...
Рейтинг: 0 / 0
Соседние записи таблицы после сортировки.
    #39483106
shplace
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
darknesmonkshplace, спасибо!

интересный вариант, но он дольше почти в 2 раза :( 0.0253 сек.
мои 2 запроса сейчас показывают 0.0063 + 0.0078 = 0.0141.
Может еще кто-то предложит?

Я попробовал на базе в 4 млн записей.
Ваш показывает 3,35 + 2,51 = 5,86 секунд. Мой 6,77 секунд. Дольше. Зато данные были согласованы. Я проверял в момент заполнения базы.

Но вот что странно - Ваш метод не работает на такой таблице. Не могу понять почему.

Беру pid из середины примерно:
Код: sql
1.
SELECT num FROM (SELECT @i:=@i+1 num,pid FROM pictures , (SELECT @i:=0) x   ORDER BY pwidth+pheight desc ) as t WHERE t.pid=2000000 



Результат: 898148

Далее уменьшаю его на 5, получается 898143.

Далее:
Код: sql
1.
SELECT * FROM pictures ORDER BY  pwidth+pheight desc LIMIT 898143,9



Результат Вашего метода (оставил только колонку pid):
1809157
1818324
1826354
1854740
1865868
1893597
1914456
1933137
1948214

Мой выдаёт вот что:
1965958
1970319
1984287
1990827
2000000
2006517
2007773
2011192
1701342
...
Рейтинг: 0 / 0
Соседние записи таблицы после сортировки.
    #39483176
darknesmonk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
shplace,

у меня работает и Ваш метод и мой. только у меня полей больше, пришлось перечислять их.
...
Рейтинг: 0 / 0
Соседние записи таблицы после сортировки.
    #39483301
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
darknesmonk,

как бэ не лучший ты запрос для оптимизации выбрал.
...
Рейтинг: 0 / 0
Соседние записи таблицы после сортировки.
    #39483368
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
darknesmonkделаю выборку с сортировкой pwidth+pheight (ширина+высота рисунка)Крайне неудачный выбор. Эта сортировка гарантирует фуллскан и файлсорт. Если сортировка по этому критерию действительно очень важна - пересмотрите структуру хранения.
Первый вариант - дополнительное поле, хранящее эту сумму и обновляемое из триггера. Правда, получается избыточность и потенциальное рассогласование данных.
Второй вариант - то же, но не дополнительно, а взамен одного из двух полей. Если одно из этих полей не участвует в обработках (сортировках, отборах и связываниях), а только отдаётся в выходном наборе - это лучший вариант.

В случае же, если версия сервера не младше 5.7.6, возможно использование GENERATED COLUMN . Первый вариант аналогичен STORED полю, второй - VIRTUAL полю. На InnoDB оба варианта допускают создание по ним индекса.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Соседние записи таблицы после сортировки.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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