Тема: Оптимізувати код, при використанні змінних @. + обчислення в запитах
Ще один з варіантів вибірки деякої кількості випадкових рядків.
КОД:
Спочатку генерується стовпчик з унікальними рандом-значеннями (integer) = numrandom.num2
Потім виконується вибірка з таблиці відповідних рядків, якщо news2.ID цих рядків (унікальне) і дорівнює кожному значенню з генерованої таблиці стовпчика numrandom.num2.
- цей код буде доданий до теми варіантів і ефективності вибірок рандом-даних, з відповідним описом
- вважав, що використання змінних SET @lalala, може мати деякий сенс в вирішенні у вибірках
- вибірка дійсно виконує умови, набирає рівно стільки рандомних (випадкових) значень, скільки потрібно, без повторів значень; тобто рівно "5" рядків, не більше і не менше.
- вибірка не може перевіряти рядки, номери яких не існують згідно отриманого переліку раному (це не потрібно)
- вибірка не може оминати рядки, якщо вони мають в особливій колонці особливе значення (але потрібно)
SET @count=0;
SET @in1=0; SET @in2=0; SET @in3=0; SET @in4=0; SET @in5=0;
SET @inX=0;
SELECT DISTINCT `blog`.`id`, `blog`.`zag_ua`, `blog`.`minitxt_ua`
FROM
(SELECT
blogR.id, @inX:=ROUND( RAND()* ((SELECT MAX(`id`) FROM `news2`)-100) )+100 num2, @in1,@in2,@in3,@in4,@in5
FROM
# blogR.id - вибірка для розширеного розуміння, немає в ній необхідності
# , як і в вибірках @in1,@in2,@in3,@in4,@in5 (вони тільки для налагодження)
`news2` as blogR
where
IF(
@inX NOT in (@in1,@in2,@in3,@in4,@in5),
@count:= if(
(select concat (@in5:=@in4, @in4:=@in3, @in3:=@in2, @in2:=@in1, @in1:=@inX) ),
(select @count:=@count+1),
@count),
@count
)<5 AND @in5=0
) AS numrandom,
`news2` as blog
WHERE blog.id IN (numrandom.num2) AND @in5<>0
# в останньому рядку коду AND @in5<>0 - я ще повинен перевірити до чого я так ставив
# умову, що рандомний рядок відповідатиме рядку з додатковою умовою AND news2.active_news ='A' не знаю куди поставити
Питання:
1. як можна змінити примусові обчислення?
що буде швидше і оптимальніше аніж такий код:
@count:= if(
# примусове обчислення 5-ти змінних, але за допомогою SELECT і додаткової функції, яка виконує додаткову непотрібну операцію
(select concat (@in5:=@in4, @in4:=@in3, @in3:=@in2, @in2:=@in1, @in1:=@inX) ),
# якщо умова IF виконується, а вона завжди виконується!, тоді збільшуємо значення @count на 1 теж за допомогою SELECT
(select @count:=@count+1),
# якщо IF не виконуєтся, а цього просто не може бути за даним кодом, тому просто для логіки повертаємо @count, хоча можемо поставити аби яке цифрове значення.... для швидкості
@count)
2. чи потрібно змінювати вираз, і чи буде обчислення швидше?, (сам не перевіряв)
select concat (@in5:=@in4, @in4:=@in3, @in3:=@in2, @in2:=@in1, @in1:=@inX)
на іншу логіку, select concat (@inTXT, ', ', @inX, ' ')
і перевіряти тоді не виразом IF(@inX NOT in (@in1,@in2,@in3,@in4,@in5) ...
а виразом IF( LOCATE(' '+@inX+' ', @inTXT)=0 ... ... ,чи так можна? без (LOCATE(concat(..), ...)
3. DISTINCT таки є в коді, використовую бо в мене помилка в підготовці умов?
Не розумію, чому в вибірці SELECT `blog`.`id`, `blog`.`zag_ua`, `blog`.`minitxt_ua`
мені знадобився DISTINCT , не розумію чому генерується зайвий рядок або рядки, в умові IF(),
якщо виник збіг деякого нового отриманого значення @inX, з значенням із згенерованого набору @in1-@in4
Тепер код, який можна вважати зменшеним від першого з видаленням зайвого і зменшенням умов: