21

(13 відповідей, залишених у Бази даних)

1. Створення таблиці, загальним розміром 600000 рядків ( без 2 рядків):
з донорів цієї таблиці (було 7 рядків), для наповнення БД, замість PHP-запитів навчився створювати процедури всередині самої БД

>> Запит був успішно виконаний ( запит зайняв 49.0361 сек. )

Обсяг таблиці склав, у вигляді файлів: 5,87 МБ + 3,21 ГБ (3450845640 + 6158336 = 3457003976 байт, = 3296,856 МБ ),
.. на більше не вистачає об'єму логічного диска


2. об'єм даних повторюється кожні 7 рядків таблиці й дорівнює заповненню по-символам, приблизно, 39,4 КБ (40 385 байт), формат Win-1251
У таблиці (у кожному рядку) використовуються 6 текстових стовпчиків і 3 службових, ця інформація забезпечить розуміння, що пошук складний (з зміненими по розміру рядками).
Текстові рядки складаються з: 2 стовпчика "varchar(80)" і 4 стовпчика "text"


3. Перший запит ( перехід до останньої 30-тки рядків)

SELECT * 
FROM  `news2` 
LIMIT 599970, 30

>> зайняв ледве більше 10 секунд,
>> усі інші запити, по зсуву 30 у будь-яку сторону - (599,998 усього записів/рядків таблиці, запит зайняв 1.1660 сек.)

випадковий запит

SELECT * 
FROM  `news2` 
LIMIT 32000, 30

>> видало (30 усього, запит зайняв 0.0685 сек.)

випадковий запит
SELECT *
FROM  `news2`
LIMIT 320000, 30
>> видало (30 усього, запит зайняв 0.6230 сек.)

22

(13 відповідей, залишених у Бази даних)

Анатолій написав:

... і вас не влаштовує, то можна в студію озвучити, які саме критерії вас не влаштовують, цікаво


Мабуть зроблю так (деякі умови повторю з першого повідомлення):
- Є таблиця, з індексованим стовпчиком NNN,
- дані INT, у стовпчику NNN не послідовні і можуть бути з пропусками: 1, 3, 55, 60
- при рандом-вибірки, слідувати умовам: що NNN >99 та activate="A", тобто активні новини які мають індекс не менше 100
- не використовувати ORDER BY rand()
- підвищити швидкість якщо можливо.


Рішення:
- Створення процедури , яка створить рядок для виконання пошуку по значенням з допомогою оператора переліку: IN (...)
.... тобто SELECT news FROM table1 WHERE nnn IN (3,55,......);
- ІN (...) створити без допомоги рандому PHP, а тільки засобами SQL

- МОЯ невизначеність.  *SCRATCH*  Я не знаю як працює процедура тут ==>. Якщо звертаюсь до процедури, то доки вона виконується - паралельно інша особа із своїм зверненням до БД чекає чи виконує свої дії?
... я б хотів закрити можливість зміни кількість рядків таблиці table1 або значення активності activate="A" доки не виконаю рандом-пошук.

Рішення, вдосконалення #1:
- створення додаткової таблиці-індексу, вона матиме посилання тільки на ті рядки основної таблиці, якщо там виконується умова: рядок з номером не пропущений (існує), NNN >99 та activate="A"
- ця створена додаткова таблиця з зовнішнім індексом на таблицю table1, для легкого визначення рандомних 6-ти рядків, якщо умови table2.ID=RAND()*кількість_рядків_ID/COUNT?/ та  table2.KEY = table1.NNN

Рішення, вдосконалення #2:
- Створення тригерів, CREATE TRIGGER, які б реагували на додання новин, зміни активності, видалення рядка з новиною. І відповідним коригуванням додаткової таблиці з зовнішнім індексом. (Збільшує час на редагування новин), але зберігає цілісність (реляційну БД). Не впливає на рандомний пошук після вдосконалення #1.


Рішення, вдосконалення #3:
Це дійсно нахабство після умов #2 і #1, але хочу ще зрозуміти і навіть створити (експеримент)...
- окрему таблицю, у якій будуть зберігатись 6-ть рандомних новин
- цю таблицю оновлювати раз на добу, але НЕ можливостями PHP, а чи є ЯКИЙСЬ засіб самовільної процедури у SQL яка б самостійно , раз на добу вмішувалась в рядки якоїсь таблиці і змінювала. Тобто чи є часовий тригер у SQL?

23

(13 відповідей, залишених у Бази даних)

Після вашої рекомендації вивчив і повністю проконспектував примірник з Хабру.
Це навіть удосконалило і поширило деякі знання з SQL.

Але наткнувся на цей код з Хабр примірника, і вважаю його хибним, може помиляюсь:?

Анатолій написав:

... хоча б той же Хабр і не морочи собі голову

    SET iQuery = CONCAT(iQuery, '(SELECT * FROM `', aSchema, '`.`', aTable,
      '` LIMIT ', ROUND(RAND(UNIX_TIMESTAMP() + aNumRows) * iNumRows), ', 1)');

ROUND(RAND(UNIX_TIMESTAMP() + aNumRows) * iNumRows)

- якщо беремо, що у нас є вибірка (великої) кількості рядків, і iNumRows це обчислена кількість рядків (нехай у нас це 100500 знайдених рядків), майже як COUNT(*), тоді формула безглузда
- aNumRows - вважаю, що це кількість шуканих ВПАДКОВИХ (РАНДОМ) рядків, їх кількість (нехай у нас 10)
- UNIX_TIMESTAMP() - так розумію що це використання часу, для перероблення під РАНДОМ, і використання отриманого часу як змінна у вигляді INT , нехай видало 882226357, але обнулення раз на 100 рік ?! чи навіть раз на Добу ?! )))

Виходить приклад:

ROUND(RAND(882226357 + 10) * 100500)

тоді він в голову не лізе!
Це вихід за межі пошукового об'єму - закреслив
Це матиме майже статичне значення... посеред всієї вибірки

24

(13 відповідей, залишених у Бази даних)

Невже все так просто і не треба бути "завумним", якщо поля індексовані?

The prior postings on random rows selections have shown:

SELECT * FROM foo ORDER BY count*RAND() LIMIT 5;

швидкість за рахунок команди ORDER BY і кожен рядок рандомний, тільки потім ліміт 5 ???

Шукаю варіант рішення моєї задачі.
Повернувся до свого робочого сайту і хочу доробити.


!!!_ У мене є таблиця БД MySQL 5,
- в таблиці новини йдуть підряд,
- є ключовий стовпчик (аутоінкрементний) в таблиці
- є нумерований стовпчик UNIQUE, нехай назва NNN
- новини починаются з номеру NNN >= 99

Що хочу:
зараз 6-ть новин, хочу робити багато новин, і щоб вони при запиту до сторінки відкривались рандомно 6-ть аби яких новин.



1. перший варіант - робити рандом пошук кожної строки в Таблиці БД і так 6-ть раз на кожне відкривання сторінки

SELECT * FROM `table` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` ) ORDER BY id LIMIT 1;

http://akinas.com/pages/en/blog/mysql_random_row/

2. другий варіант, запит до БД, для отримання деяких даних MAX(NNN) , COUNT(*), і інших... а потім створювати рандом 6-ти чисел у PHP, потім новий один запит типу. Таким чином хоч я один буду керувати змінами новин, але вважаю не достить кмітливим, з боку запитів SQL, тобто в теорії, доки зроблю обчислення 6-ти номерів строк у БД, хтось інший може їх змінити (видалити), тобто хочу розуміти на перспективу і не робити таку каку:

====== 2.1. ====
http://biznesguide.ru/coding/172.html

$offset_result = mysql_query("SELECT MAX(id) AS max, MIN(id) AS min FROM `table`");
$offset_row = mysql_fetch_object( $offset_result );
$max = $offset_row->max;
$min = $offset_row->min;
 
$n = 5; // кількість записів, для отримання
$i = 0;

$ids = array();

while($i < $n){
  $ids[] = mt_rand($min,$max);
}
 
$result = mysql_query( "SELECT * FROM `table` WHERE id IN(".implode(',',$ids).") LIMIT ".$n);

===== 2.2 ==========
SQL .. MAX(NNN) , COUNT(*)
PHP .. $nnn=array[10000, 60000, 110000, 160000, 210000, 260000, 310000, 360000, 410000, 460000] - після створення значень, але поза SQL
SQL .. SELECT id FROM table1 WHERE nnn IN ($nnn[10000], ..... 60000, 110000, 160000, 210000, 260000, 310000, 360000, 410000, 460000);
.... приклад був у коментах тут - http://домен агресора/post/54176/



3. щось цікаве знайшов
тут - http://www.askdev.ru/question/20399/%D0 … %BE%D0%BA/
http://stackoverflow.com/questions/4329 … -rows-fast
http://www.warpconduit.net/2011/03/23/s … k-results/ - !

Multiple Rows at once - http://jan.kneschke.de/projects/mysql/order-by-rand/
..на Рос.: http://hudson.su/2010/09/16/mysql-optim … r-by-rand/

і тут - http://домен агресора/post/207096/
http://alexvolkov.ru/mysql-rand-how-to- … om-db.html
http://biznesguide.ru/coding/172.html


Як мені бути, яким шляхом йти??? які вимоги для колонок обов'язкові? Індекс*?
1) http://домен агресора/post/54176/ - тут є приклад об'єднання шляхом UNION , за методом SQL та є SQL + PHP
2) якось можна методом WHERE nnn IN тільки SQL з розширенням коду? щоб все влізло тільки в SQL ? та швидко шукало ..

26

(7 відповідей, залишених у Бази даних)

Теоретично:
`zno_questions-toppic` ... помилка в назві колонки таблиці або не рекомендована назва (чому в назві стовпчика дефіс '-')
RAND(`zno_answers-answer`) .. поки що не бачив рандом, по назві, бачив рандоми по числах RAND (x)