簡體   English   中英

在Laravel 5.2中從大型數據庫查詢中排除結果的最佳方法

[英]Best way to exclude results from a big db query in Laravel 5.2

我正在使用Laravel 5.2來構建一個大型產品庫存,而我在查看將顯示產品的問題時遇到問題。 這是一個例子:

我有很多產品 - 在我的數據庫中准確地超過20k。 其中大多數我想每天展示,但大約500-1000我只需要在一周的某些日子顯示。

Currenly我已經回顧了以下方法,每個方法都有其缺點:

  1. 創建表product_availability,其中每行包含product_id,weekday和available(true / false)列。 然而,根據這種結構,我有7行提供1個產品的信息,整個表格將包含~14萬行,我認為這不是一個好主意 - 因為大多數產品無論如何都會每天都可用而且只有500 -1000不會。

  2. 我的第二個猜測是簡單地在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對於這個解決方案的問題在於它也將是一個緩慢而沉重的方法。

  1. 我的第三個猜測是倒退,不是檢查產品今天是否可用,而是檢查它不在哪一天。 這樣我就可以獲得'availability'列為null的所有產品,對於這些,它不是運行if語句然后以某種方式添加它們,但我不知道如何構造它。

所以我的問題是:

什么是最快的查詢來獲得今天可用的所有產品,請記住,只有很小一部分產品不可用(如何排除它們,也許)?

我認為你的第一個選擇是最好的解決方案(雖然有一些變化)。

我建議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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM