[英]Best way to exclude results from a big db query in Laravel 5.2
我正在使用Laravel 5.2來構建一個大型產品庫存,而我在查看將顯示產品的問題時遇到問題。 這是一個例子:
我有很多產品 - 在我的數據庫中准確地超過20k。 其中大多數我想每天展示,但大約500-1000我只需要在一周的某些日子顯示。
Currenly我已經回顧了以下方法,每個方法都有其缺點:
創建表product_availability,其中每行包含product_id,weekday和available(true / false)列。 然而,根據這種結構,我有7行提供1個產品的信息,整個表格將包含~14萬行,我認為這不是一個好主意 - 因為大多數產品無論如何都會每天都可用而且只有500 -1000不會。
我的第二個猜測是簡單地在products表中添加一個'availability'列,它將包含以下格式的JSON字符串:
{“mo”:“true”,“tu”:“false”,“we”:“false”,“th”:“true”,“fr”:“false”,“sa”:“false”,“ su“:”true“}
然后我會這樣查詢:
$weekday = date('N');
switch ($weekday) {
case '1':
$builder->where('$availability->mo', 'true');
break;
case '2':
$builder->where('$availability->tu', 'true');
break;
case '3':
$builder->where('$availability->we', 'true');
break;
case '4':
$builder->where('$availability->th', 'true');
break;
case '5':
$builder->where('$availability->fr', 'true');
break;
case '6':
$builder->where('$availability->sa', 'true');
break;
case '7':
$builder->where('$availability->su', 'true');
break;
}
但IMO對於這個解決方案的問題在於它也將是一個緩慢而沉重的方法。
所以我的問題是:
什么是最快的查詢來獲得今天可用的所有產品,請記住,只有很小一部分產品不可用(如何排除它們,也許)?
我認為你的第一個選擇是最好的解決方案(雖然有一些變化)。
我建議product_availability
的表結構類似於:
| id | product_id | mon | tue | wed | thu | fri | sat | sun |
| 1 | 13403 | 1 | 0 | 1 | 0 | 1 | 0 | 0 |
然后你可以查詢類似的東西:
SELECT
products.*
FROM
products
LEFT JOIN
product_availability
ON
product_availability.product_id = products.id
WHERE
# show if no entry here (i.e. always to be shown)
product_availability.id IS NULL
OR
# only want to show specific days
product_availability.id IS NOT NULL AND CASE
WHEN DAYOFWEEK(CURDATE()) = 1 THEN `sun` = 1
WHEN DAYOFWEEK(CURDATE()) = 2 THEN `mon` = 1
WHEN DAYOFWEEK(CURDATE()) = 3 THEN `tue` = 1
WHEN DAYOFWEEK(CURDATE()) = 4 THEN `wed` = 1
WHEN DAYOFWEEK(CURDATE()) = 5 THEN `thu` = 1
WHEN DAYOFWEEK(CURDATE()) = 6 THEN `fri` = 1
WHEN DAYOFWEEK(CURDATE()) = 7 THEN `sat` = 1
END
這將顯示所有產品。 如果product_availability
有產品ID的條目,那么它將獲得當前的一周(如果您願意,可以使用其他方法替換它),並查看相應的日期是否有1
來顯示它。
只有很小一部分不可用
在這種情況下,您只需要在product_availability
添加一個條目。
這是一個小提琴: http ://sqlfiddle.com/#!9/ c2bbf1/3
希望這可以幫助 :)
編輯:您可以用來轉換為雄辯查詢的一些方法:
->leftJoin('product_availability', 'products.id', '=', 'product_availability.product_id')
->whereNull('product_availability.id')
->orWhere(function ($query) {
$query
->whereRaw('(product_availability.id IS NOT NULL AND CASE
WHEN DAYOFWEEK(CURDATE()) = 1 THEN `sun` = 1
WHEN DAYOFWEEK(CURDATE()) = 2 THEN `mon` = 1
WHEN DAYOFWEEK(CURDATE()) = 3 THEN `tue` = 1
WHEN DAYOFWEEK(CURDATE()) = 4 THEN `wed` = 1
WHEN DAYOFWEEK(CURDATE()) = 5 THEN `thu` = 1
WHEN DAYOFWEEK(CURDATE()) = 6 THEN `fri` = 1
WHEN DAYOFWEEK(CURDATE()) = 7 THEN `sat` = 1
END)');
});
或者你可以做DB :: raw查詢
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.