濮阳杆衣贸易有限公司

主頁 > 知識庫 > MySQL 使用自定義變量進行查詢優(yōu)化

MySQL 使用自定義變量進行查詢優(yōu)化

熱門標簽:南太平洋地圖標注 北京金倫外呼系統(tǒng) 400電話變更申請 400電話辦理服務價格最實惠 呂梁外呼系統(tǒng) 大豐地圖標注app 催天下外呼系統(tǒng) 武漢電銷機器人電話 html地圖標注并導航

優(yōu)化排序查詢

自定義變量的一個重要特性是你可以同時將該變量的數學計算后的結果再賦值給該變量,類似于我們的 i = i + 1這種方式。下面是一個用于計算數據表行號的例子:

SET @rownum := 0;
SELECT actor_id, @rownum := @rownum + 1 AS rownum
FROM sakila.actor LIMIT 3;

actor_id rownum
1 1
2 2
3 3

得到的結果也許看起來沒什么意義,這是因為主鍵是從1自增的,因此行號和主鍵值是一樣的。但是,這種方式可以用于做排序。例如需要查詢飾演電影數量最多的前10名演員,通常的做法是像下面這樣寫:

SELECT actor_id, COUNT(*) as cnt
FROM sakila.film_actor
GROUP BY actor_id
ORDER BY cnt DESC
LIMIT 10;

得到的結果也許看起來沒什么意義,這是因為主鍵是從1自增的,因此行號和主鍵值是一樣的。但是,這種方式可以用于做排序。例如需要查詢飾演電影數量最多的前10名演員,通常的做法是像下面這樣寫:

SELECT actor_id, COUNT(*) as cnt
FROM sakila.film_actor
GROUP BY actor_id
ORDER BY cnt DESC
LIMIT 10;

如果我們要獲得相應的排名值的話,則可以引入變量來完成:

SET @curr_cnt := 0, @prev_cnt := 0, @rank := 0;
SELECT actor_id,
	@curr_cnt := cnt AS cnt,
  @rank 		:= IF(@prev_cnt > @curr_cnt, @rank+1, @rank) as rank,
  @prev_cnt	:= @curr_cnt AS dummy
FROM (
  SELECT actor_id, COUNT(*) AS cnt
  FROM sakila.film_actor
	GROUP BY actor_id
	ORDER BY cnt DESC
	LIMIT 10
) as der;

這里是將飾演電影的數量賦值給了 curr_cnt 變量,使用了prev_cnt 存儲前一個演員的參演數量。排名從第一名開始的,如果后面的演員的數量和前一個演員的數量不同,則排名要往下(+1),如果相同則和前一個演員的排名相同。通過這種方式可以直接從查詢結果中得到演員的排名,而不需要再從數據庫查詢做二次處理(當然也可以通過程序代碼實現)。

避免重復獲取剛剛修改的數據行

如果想在更新數據行的時候再重新獲取數據行的信息,往往需要再讀取一次數據庫。這是因為 MySQL 不像 PostgreSQL 的 UPDATE RETURNING 功能可以同時返回更新后的數據行,而只是返回更新影響的行數。但是,我們可以通過自定義變量完成這樣的操作。例如,獲取剛剛被修改過更新時間的行,不使用自定義變量的話需要做一次額外的查詢:

UPDATE tb1 SET lastUpdated = NOW() WHERE id = 1;
SELECT lastUpdated FROM tb1 WHERE id = 1;

而使用自定義變量的時候可以避免這種情況:

UPDATE tb1 SET lastUpdated = NOW() WHERE id = 1 AND @now  := NOW();
SELECT @now;

雖然還是有一個查詢操作,但是后面的查詢操作不再需要訪問數據庫了。

懶加載的聯合查詢

假設我們需要寫一個聯合查詢完成如下任務:在聯合的分支上查找匹配的數據行,如果找到了就跳過其他分支。y這種情況發(fā)生在需要從熱區(qū)數據或低頻訪問數據中查找(比如近期訂單和歷史訂單)。這是下面針對用戶查詢的一個普通的 SQL:

SELECT id FROM users WHERE  id = 123
UNION ALL
SELECT id FROM users_archived WHERE id = 123;

這個查詢會先從當前正在使用的用戶表查詢 id 為123的用戶,然后 在從已歸檔的用戶表找同樣 id 的用戶。但是,這種寫法比較低效,即便是在 users 表找到了想要找的用戶,還是需要從users_archived 這個表再找一次,而實際用戶 id 為123的只會存在其中的一張表中或兩張表的數據是一樣的。通過懶加載的聯合查詢,可以避免這種情況——只有在第一個分支沒有找到數據時才進行第二個分支的查詢。因此可以使用 MySQL 的 GREATEST 方法來作為查詢結果的容器以避免多返回數據列。

SELECT GREATEST(@found := -1, id) AS id, users.name, 'users' as which_tb1
FROM users WHERE id = 123
UNION ALL
	SELECT id, users_archived.name, 'users_archived'
  FROM users_archived WHERE id = 123 AND @found IS NULL
UNION ALL
	SELECT 1, '', 'reset' FROM DUAL WHERE ( @found := NULL) IS NOT NULL;

上述的查詢如果第一行有結果,則@found 不會被賦值,因而是 NULL,從而執(zhí)行第二次查詢。而第三次的 UNION 實際沒什么效果,只是為了將@found恢復到 NULL 值,以便這段 SQL 可以重復執(zhí)行。另一個驗證的方法是對同一張表進行這樣的操作,可以發(fā)現實際只會返回一行數據或不返回數據(查詢不到數據時)。

SELECT GREATEST(@found := -1, `id`) AS `id`, `infocenter_city`.`name`, 'city' as which_tb1 
FROM `infocenter_city` WHERE `id` = 460100 
UNION ALL 
	SELECT `id`, `infocenter_city`.`name`, 'infocenter_city' 
	FROM `infocenter_city` WHERE id = 460100 AND @found IS NULL 
UNION ALL 
	SELECT 1, '', 'reset' FROM DUAL WHERE ( @found := NULL) IS NOT NULL

以上就是MySQL 使用自定義變量進行查詢優(yōu)化的詳細內容,更多關于MySQL 用自定義變量進行查詢優(yōu)化的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • MySQL百萬級數據分頁查詢優(yōu)化方案
  • 理解MySQL查詢優(yōu)化處理過程
  • mysql查詢優(yōu)化之100萬條數據的一張表優(yōu)化方案
  • 詳解MySQL 聯合查詢優(yōu)化機制
  • MySQL查詢優(yōu)化必備知識點總結
  • MySQL查詢優(yōu)化之查詢慢原因和解決技巧
  • MySQL之select in 子查詢優(yōu)化的實現
  • MySQL千萬級大數據SQL查詢優(yōu)化知識點總結
  • Mysql慢查詢優(yōu)化方法及優(yōu)化原則
  • 通過MySQL慢查詢優(yōu)化MySQL性能的方法講解
  • MySQL 百萬級數據的4種查詢優(yōu)化方式

標簽:南充 西寧 徐州 自貢 無錫 龍巖 迪慶 麗水

巨人網絡通訊聲明:本文標題《MySQL 使用自定義變量進行查詢優(yōu)化》,本文關鍵詞  MySQL,使用,自定義,變量,;如發(fā)現本文內容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內容系統(tǒng)采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《MySQL 使用自定義變量進行查詢優(yōu)化》相關的同類信息!
  • 本頁收集關于MySQL 使用自定義變量進行查詢優(yōu)化的相關信息資訊供網民參考!
  • 推薦文章
    长阳| 化州市| 黎川县| 温宿县| 轮台县| 东乌珠穆沁旗| 千阳县| 耒阳市| 泽州县| 四川省| 白水县| 舞阳县| 正定县| 安溪县| 岳池县| 哈尔滨市| 开阳县| 芦溪县| 台东县| 如东县| 淳安县| 沂源县| 保康县| 潜江市| 利辛县| 曲靖市| 高雄县| 墨玉县| 黔江区| 马鞍山市| 玉环县| 扎赉特旗| 苏尼特左旗| 北安市| 伊宁县| 兴海县| 高陵县| 凤城市| 华容县| 水城县| 自治县|