استعلام لما اشترى العملاء مع المنتج المدرج
سؤال
أحاول الحصول على استفسار قديم جدًا لا يمكنني لفه. والنتيجة التي أرغب في أرشيفها هي أنني أريد أن أوصي بالزائر على متجر ويب ما أظهره العملاء الآخرون ، أي ما الذي اشتروه مع المنتج الذي يبحث عنه الزائر.
لدي مسمة فرعية لكنها جداً بطيء ، يأخذ ~ 15s على ~ 8 000 000 صف.
التصميم هو أن جميع المنتجات التي يتم وضعها في سلة المستخدمين يتم الاحتفاظ بها في جدول wsBasket
وفصلها أ basketid
(الذي يرتبط في جدول آخر مع عضو).
في هذا المثال ، أود أن أدرج جميع المنتجات الأكثر شعبية التي اشترها المستخدمون مع ProductId 427 ، ولكن لا تدرج شركة ProductId 427 نفسها.
SELECT productid, SUM(quantity) AS qty
FROM wsBasket
WHERE basketid IN
(SELECT basketid
FROM wsBasket
WHERE productid=427) AND productid!=427
GROUP by productid
ORDER BY qty
DESC LIMIT 0,4;
أي مساعدة هي محل تقدير كبير! آمل أن يكون هذا منطقيًا على الأقل لشخص ما على الأقل :)
تحديث 1:شكرًا على تعليقاتك يا رفاق هنا هي إجاباتي ، لم يتناسبوا مع ملعب التعليقات.
باستخدام شرح في الاستعلام أعلاه ، حصلت على التغطيق. يرجى ملاحظة أنه ليس لدي أي فهارس على الجدول (باستثناء المفتاح الأساسي على id
-حقل) ، أريد تعديل الاستعلام للاستفادة من الفهارس ووضع الفهارس على المفاتيح الصحيحة.
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
| 1 | PRIMARY | wsBasket | ALL | NULL | NULL | NULL | NULL | 2821 | Using where; Using temporary; Using filesort |
| 2 | DEPENDENT SUBQUERY | wsBasket | ALL | NULL | NULL | NULL | NULL | 2821 | Using where |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
المحلول
اثنين من الفهارس الواضحة لإضافتها: واحد على السلة والثانية على الإنتاجية: ثم أعد إعادة الاستعلام وشرح جديد لترى أن الفهارس تستخدم
نصائح أخرى
وكذلك ضمان وجود الفهارس المناسبة على productid
و basketid
, ، غالبًا ما تستفيد من هيكلة استعلامك كضجة بسيطة بدلاً من الاستعداد الفرعي ، خاصة في MySQL.
SELECT b1.productid, SUM(b1.quantity) AS qty
FROM wsBasket AS b0
JOIN wsBasket AS b1 ON b1.basketid=b0.basketid
WHERE b0.productid=427 AND b1.productid<>427
GROUP BY b1.productid
ORDER BY qty DESC
LIMIT 4
بالنسبة لي ، على مجموعة بيانات ربما تماثل ، أدت إلى اثنين select_type: SIMPLE
الصفوف في EXPLAIN
المخرجات ، في حين أن طريقة السعة الفرعية تصنع الأداء الرهيب DEPENDENT SUBQUERY
. وبالتالي ، كان الانضمام أكثر من طراز من حيث الحجم بشكل أسرع.
الحقلان اللذين تستخدمهما بشكل رئيسي للبحث في هذا الاستعلام هما منتجان و BasketId.
عندما تبحث عن السجلات التي تحتوي على ProductID تساوي 427 ، فإن قاعدة البيانات ليس لديها أدنى فكرة عن مكان العثور على هذا السجل. لا يعلم حتى أنه إذا وجدت مطابقة واحدة ، فلن يكون هناك واحد مطابق آخر ، لذلك يجب أن تبحث من خلال الجدول بأكمله ، وربما الآلاف من السجلات.
الفهرس هو ملف منفصل يتم فرزه ، ويحتوي فقط على الحقل/الحقل الذي تهتم به. لذا فإن إنشاء فهرس يوفر قدراً هائلاً من الوقت!