PDA

View Full Version : به دست آوردن نتایج تصادفی در دیتابیس های حجیم



peachcms
جمعه 02 دی 1390, 23:53 عصر
با سلام

برای یک سیستم کلیکی که بنر های زیادی درش قرار میگیرند و براش سرعت بالای به دست آوردن نتایج تصادفی مهم هست. درضمن نتایج تکراری نباشند

چه الگوریتمی رو پیشنهاد میکنین. لطفا با ذکر مثال بفرمایید

peachcms
شنبه 03 دی 1390, 13:23 عصر
دوستان لطف کنند جواب بدند چون واجب هست

ممنون

peachcms
شنبه 03 دی 1390, 14:11 عصر
برای دستیابی تصادفی به سطر های دیتابیس عرض کردم

AMIBCT
شنبه 03 دی 1390, 14:40 عصر
بهترین روش این هست:
http://www.greggdev.com/web/articles.php?id=6

روی ستون اصلی باید Index داشته باشید
بزرگترین شناسه‌ی جدول رو پیدا می‌کنید
یک عدد تصادفی کوچکتر از اون رو انتخاب می‌کنید
ردیف مورد نظر رو از بانک دریافت می‌کنید

به این صورت تمام فعالیت‌ها روی Index انجام می‌شه و سرعتی بیشتر از این ممکن نیست

peachcms
شنبه 03 دی 1390, 18:08 عصر
بهترین روش این هست:
http://www.greggdev.com/web/articles.php?id=6

روی ستون اصلی باید Index داشته باشید
بزرگترین شناسه‌ی جدول رو پیدا می‌کنید
یک عدد تصادفی کوچکتر از اون رو انتخاب می‌کنید
ردیف مورد نظر رو از بانک دریافت می‌کنید

به این صورت تمام فعالیت‌ها روی Index انجام می‌شه و سرعتی بیشتر از این ممکن نیست


این کد رو برای سیستم خمکاری در فروش و سیستم کلیک میخام

1 - فرض کنین کاریر خواست 5 تا بنر رو نمایش بده یهنی 5 تا رکورد برگردونده بشه این الان لیمیت 1 هست و نمیشه بیشتر از 1 کر چون دیگه تصادفی نیست! باید 5 بار این کوئری تکرار بشه؟ سرعت گرفته نمیشه؟

AMIBCT
یک شنبه 04 دی 1390, 11:30 صبح
بستگی دارد

اگر تعداد رکوردهای موجود در جدول شما زیاد باشد
ممکن است 5 بار درخواست از یک بار درخواست با استفاده از order by rand سریع‌تر باشد

دستور order by rand خیلی سنگین است

امیـرحسین
یک شنبه 04 دی 1390, 20:03 عصر
این بهتر تابع ()RAND عمل مبکنه:

$rowsCount = $pdo->query("SELECT COUNT(id) FROM ads WHERE 1")->fetchColumn();
$offest = 5;
$start = rand(0, $rowsCount-$offest);
$sql = "SELECT * FROM ads WHERE 1 LIMIT $start , $offest";

در MySQL 5.5 میتونید با Stored Procedure تعداد سطرها رو با کوئری بگیرید که سریعتر شه. مثل این مثلا:
DROP PROCEDURE IF EXISTS randomAds$$
CREATE PROCEDURE randomAds(resultsNumber SMALLINT(2))
BEGIN
DECLARE total INT(10);
SELECT COUNT(id) FROM ads WHERE 1 INTO total;
SELECT SELECT * FROM ads WHERE 1 LIMIT total , resultsNumber;
END$$

$randomAdsRows = $pdo->query("CALL randomAds(10);")->fetchAll(PDO::FETCH_ASSOC);

AMIBCT
دوشنبه 05 دی 1390, 10:41 صبح
کدی که شما نوشتید از صفر تا 5 ردیف پشت سر هم رو بر می‌گردونه
یعنی ممکنه هیچ چیزی بر نگرداند(اگر شناسه‌ها پشت سر هم نباشند و بینشان فاصله باشد)
و چیزی که بر می‌گرداند 5 ردیف پشت سر هم است نه اتفاقی

امیـرحسین
دوشنبه 05 دی 1390, 11:29 صبح
مدلی که من استفاده کردم یک بازه‌ی ۵تایی بصورت رندم انتخاب میکنه و چون در محدوده‌ی سطرهاست همیشه مقدار برمیگردونه. اگر بجای ۵ فقط یکی بخوایم میشه رندوم واقعی!
در هر صورت اینها رو هم ببینید:
Selecting random rows (http://explainextended.com/2009/03/01/selecting-random-rows/)
An alternative to ORDER BY RAND() for MySQL (http://www.electrictoolbox.com/msyql-alternative-order-by-rand/)