電商場景下的常見業務SQL處理

来源:https://www.cnblogs.com/huchong/archive/2019/01/09/10237854.html
-Advertisement-
Play Games

1. 如何對評論進行分頁展示 一般情況下都是這樣寫 SELECT customer_id,title,content FROM product_comment WHERE audit_status = 1 AND product_id =199726 LIMIT 0,15;; 我們來看看它的執行計劃 ...


1. 如何對評論進行分頁展示

一般情況下都是這樣寫

 SELECT customer_id,title,content FROM product_comment WHERE audit_status = 1 AND product_id =199726 LIMIT 0,15;;

我們來看看它的執行計劃

可以看到possible_keys、key、key_len的值均為NULL,說明這條SQL在product_comment 表上是沒有可用的索引的,取出9593行過濾度為1%

1. 建立索引,優化評論分頁查詢

根據我們索引規範可以考慮在where條件上建立索引
where條件有兩個欄位,我們可以通過以下語句計算一下兩列數據在表中的區分度

計算欄位數據區分度,建立索引

SELECT COUNT(DISTINCT audit_status)/COUNT(*) AS audit_rate,COUNT(DISTINCT product_id)/COUNT(*) AS product_rate FROM product_comment;

比值越接近1,代表區分度越好,我們應該把區分度好的列放到聯合索引的左側

我們現在建立索引後,再來看看執行計劃

可以看到查詢時運用到了聯合索引,只查詢出一條數據,就能返回我們需要的數據了,過濾程度是百分之百,我們完成了第一步優化

資料庫的訪問開銷 = 索引 IO + 索引全部記錄結果所對應的一個表數據的 IO

缺點

這種SQL語句查詢的缺點是,越往後翻頁,比如幾千頁之後,效率會越來越差,查詢時間也會越來越長,尤其表數據量大的時候更是如此

適用場景

它的適用場景是表的結果集很小,比如一萬行以下時,或查詢條件非常複雜,比如涉及到多個不同的查詢判斷,或是表關聯時使用

2. 進一步優化評論分頁查詢,SQL語句改寫

改寫後的SQL語句:

SELECT t.customer_id,t.title,t.content 
FROM (
SELECT customer_id  FROM product_comment WHERE  product_id =199726 AND audit_status = 1 LIMIT 0,15
)a JOIN product_comment t 
ON a.customer_id = t.comment_id;

改寫前的SQL和改寫後的SQL查詢出來的結果集是一樣的,但是效率要高於改寫前的SQL

使用前提

使用這個SQL有一個前提是,商品評論表的主鍵是customer_id ,且是有覆蓋索引(也就是剛剛我們建立的聯合索引)

優化原理

先根據過濾條件利用覆蓋索引取出主鍵的comment_id,然後再進行排序,取出我們所需要的數據的行數,然後再和評論表通過主鍵進行排序來取出其他的欄位,
這種方式的數據開銷是索引 IO +索引分頁後的結果(15行數據)的表的IO,

優點

比改寫前的SQL在IO上要節省很多,這種改寫方式的優點是在每次翻頁的所消耗的資源和時間基本是相同的,不會越往後翻頁,效率越差

應用場景:

當查詢和排序欄位(即where子句和order by子句所涉及的欄位),有對應的覆蓋索引的情況下使用
並且查詢的結果集很大的情況下也是適用於這種情況的

二. 如何刪除重覆數據

要求

刪除評論表中對同一訂單同一商品的重覆評論,只保留最早的一條

步驟一

查看是否存在對於同一訂單同一商品的重覆評論,如果存在,進行後續步驟

查詢語句:

SELECT order_id,product_id,COUNT(*) FROM product_comment
GROUP BY order_id,product_id HAVING COUNT(*) > 1;

步驟二

備份product_comment表(避免誤刪除的情況)

備份語句:

 CREATE  TABLE bak_product_comment_190108 AS  SELECT * FROM product_comment;

如果提示:

錯誤代碼:1786 Statement violates GTID consistency:CREATE TABLE ... SELECT.

則換用下麵的語句

    CREATE  TABLE bak_product_comment_190108 AS  LIKE  product_comment;
    INSERT INTO bak_product_comment_190108  SELECT * FROM product_comment;
錯誤代碼:1786
Statement violates GTID consistency:CREATE TABLE ... SELECT.

錯誤原因

這是因為在5.6及以上的版本內,開啟了 enforce_gtid_consistency=true 功能導致的,MySQL官方解釋說當啟用 enforce_gtid_consistency 功能的時候,MySQL只允許能夠保障事務安全,並且能夠被日誌記錄的SQL語句被執行,像create table … select 和 create temporarytable語句,以及同時更新事務表和非事務表的SQL語句或事務都不允許執行。

解決辦法

方法一

修改 :

SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = off;

配置文件中 :

ENFORCE_GTID_CONSISTENCY = off;

方法二:

create table xxx as select 的方式會拆分成兩部分。

create table xxxx like data_mgr;
insert into xxxx select *from data_mgr;

如果表數據量比較大,則使用mysql dump的方式導出成文件進行備份

步驟三

刪除同一訂單的重覆評論

刪除語句:

DELETE a FROM product_comment a 
JOIN(
SELECT order_id,product_id,MIN(comment_id) AS comment_id 
FROM product_comment
GROUP BY order_id,product_id 
HAVING COUNT(*) > 1
) b on a.order_id = b.order_id AND a.product_id = b.product_id
AND a.comment_id > b.comment_id;

三. 如何進行分區間統計

要求

統計消費總金額大於1000元的,800到1000元的,500到800元的,以及500元以下的人數

SQL語句

SELECT 
COUNT(CASE WHEN IFNULL(total_money,0) >= 1000 THEN a.customer_id END) AS '大於1000'
,COUNT(CASE WHEN IFNULL(total_money,0) >= 800 AND IFNULL(total_money,0)<1000 
    THEN a.customer_id END) AS '800~1000'
,COUNT(CASE WHEN IFNULL(total_money,0) >= 500 AND IFNULL(total_money,0)<800 
    THEN a.customer_id END) AS '500~800'
,COUNT(CASE WHEN IFNULL(total_money,0) < 500 THEN a.customer_id END)  '小於500'
FROM mc_userdb.customer_login a 
LEFT JOIN 
( 
SELECT customer_id,SUM(order_money) AS total_money
    FROM mc_orderdb.order_master 
    GROUP BY customer_id
    ) b
ON a.customer_id = b.customer_id

檢驗一下結果是否正確


總和是10010,說明查詢結果正確


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 線程池 簡介 1、mysql每連接每線程,mysql都分配一個單獨的線程,該線程處理客戶端發來的所有命令 2、每個線程會占用一定的系統資源,線程數越多消耗的系統資源也越多 3、線程的創建和銷毀有一定的開銷 4、當線程數過多時,如果大部分線程都處於活躍狀態,會導致頻繁的上下文切換,從而造成系統巨大的開 ...
  • 導出完成後在狀態欄中顯示Find ...
  • 節點一 alert日誌: PDB(17):Transaction recovery: lock conflict caught and ignored PDB(17):Transaction recovery: lock conflict caught and ignored PDB(17):Tra ...
  • mysql從5.0版本開始支持存儲過程、存儲函數、觸發器和事件功能的實現。 我們以一本書中的例題為例:創建xscj資料庫的存儲過程,判斷兩個輸入的參數哪個更大。並調用該存儲過程。 (1)調用 首先,創建存儲過程(procedure),名為xscj.compar 執行結果如下: 在上邊的語句中: cr ...
  • 報錯原因: 報這個錯是因為MySQL8使用了 caching_sha2_password 加密方式而之前MySQL使用的是 mysql_native_password 加密方式,而你的Navicat不支持 caching_sha2_password 加密方式造成的。 解決方案: 目前我知道的解決方案 ...
  • 前言幾個故事大數據都是騙人的,一頭豬悲催的豬數據不全不是大數據,不可信過去->將來啤酒尿布這個案例僅是一碗數據分析的“心靈雞湯”——聽起來很爽,但信不得!GFT 預測 H1N1搜索詞和H1N1敏感性關聯“預測即干涉”悖論和“菜農種菜”,過度擬合數據並非越大越好:谷歌流感趨勢錯在哪兒了?更準確的預測模... ...
  • 我們要做到不但會寫SQL,還要做到寫出性能優良的SQL語句。 1.使用表的別名(Alias): 當在SQL語句中連接多個表時, 請使用表的別名並把別名首碼於每個Column上。這樣一來,就可以減少解析的時間並減少那些由Column歧義引起的語法錯誤。 2.表的索引: 索引是表的一個概念部分,用來提高 ...
  • 一、 軟體下載 Mysql是一個比較流行且很好用的一款資料庫軟體,如下記錄了我學習總結的mysql免安裝版的配置經驗,要安裝的朋友可以當做參考哦 mysql5.7 64位下載地址: https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19- ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...