1. 程式人生 > >mysql 分組查詢取各分組的前兩名及子查詢效能優化

mysql 分組查詢取各分組的前兩名及子查詢效能優化

背景:由於專案運營需要提供各個球員(playerId)跑動距離(distance)最長的前兩場比賽資料記錄:

資料存在mongojg表中下面看第一版sql:

1.一開始不知道怎麼取跑動最好的前兩場資料所以通過取表現最好的比賽然後通過id從結果集排除再對剩下的比賽取最好表現,最後將兩次結果合併的到球員表現最好的兩場比賽(不多說都是淚)...

SELECT e.ids,
	e.matchId,
	e.playerId,
	e.distance 跑動距離,
	e.printSpeedDistance,
	e.highSpeedDistance,
	( e.printSpeedDistance + e.highSpeedDistance ) 高強度跑動距離,
	e.successPass 成功傳球次數,
	e.tackles 阻截 ,
	b.`name` from  mongojg e JOIN qiuyaunxinxix b ON e.playerId = b.id
	JOIN sheet1 c ON b.`name` = c.`球員` 
WHERE e.distance in 
(SELECT
	
	max(a.distance) 跑動距離
	 
FROM
	mongojg a
	JOIN qiuyaunxinxix b ON a.playerId = b.id
        GROUP BY a.playerId ORDER BY a.playerId);

第二版邏輯:

後來通過子查詢的方式實現了取每個球員最好的兩場比賽,不多說直接放sql:

SELECT  matchId, playerId,b.`name` 球員, distance 跑動距離,
( mj.printSpeedDistanceCounts + mj.highSpeedDistanceCounts ) 高強度跑動距離次數,
mj.successPass 成功傳球次數,
	mj.tackles 阻截 
from  mongojg mj 
JOIN qiuyaunxinxix b on mj.playerId=b.id
WHERE (
SELECT COUNT(1) from mongojg mn  
WHERE mj.playerId=mn.playerId AND mj.distance<mn.distance 
)<2
ORDER BY  mj.playerId;

可以看到第二版sql比第一版邏輯清晰了很多:加入子查詢找出子表中距離比原表大的記錄並在這些記錄中取前兩個記錄;


看看執行記錄:執行時間1.306s,使用了子查詢,下面怎麼將子查詢改寫為left join

優化三:

SELECT 
	mj.matchId,
	mj.playerId,
	b.`name` as 球員,
	mj.distance 跑動距離,mn.distance,
	( mj.printSpeedDistanceCounts + mj.highSpeedDistanceCounts ) 高強度跑動距離次數,
	mj.successPass 成功傳球次數,
	mj.tackles 阻截 
FROM
	mongojg mj
	JOIN qiuyaunxinxix b ON mj.playerId = b.id 
	LEFT  JOIN mongojg mn on mj.playerId=mn.playerId and mn.distance > mj.distance
  GROUP BY mj.matchId, mj.playerId ,mj.distance
	HAVING COUNT(mn.matchId)<2
ORDER BY
	mj.playerId;


執行時間:0.291s,可以看到改為left join連線後效率提升明顯;

下一波優化為主表playerId 新增索引:

ALTER TABLE `haha`.`mongojg` ADD INDEX `index`(`playerId`) USING BTREE;


執行時間:時間: 0.017s

相關推薦

mysql 分組查詢分組查詢效能優化

背景:由於專案運營需要提供各個球員(playerId)跑動距離(distance)最長的前兩場比賽資料記錄:資料存在mongojg表中下面看第一版sql:1.一開始不知道怎麼取跑動最好的前兩場資料所以通過取表現最好的比賽然後通過id從結果集排除再對剩下的比賽取最好表現,最後將

Sql -- 練習1 查詢每科成績的學生資訊

相關表資訊 問題 查詢每科成績前兩名的學生資訊 解決1 SELECT hs2.student_name sna, hc2.course_name cna, m1.core

mysql實現分組查詢每個班級的

1、建立表drop table student; create table student( id varchar(20),-- 編號 class varchar(20),-- 年級 score int-- 分數 );2、建立測試資料delete from studen

分組查詢每組n條記錄例項

假設有這樣一張運動員比賽成績表 tb_score 現在要求查詢出每個國家的前三名的成績記錄,查詢語句可以這樣寫: 1、 select t3.id,t3.country,t3.score fro

Oracle (03)分組子句.where條件 與 having條件的區別.查詢.DDL.DML.資料的增刪改.TCL

昨天作業的回顧 ** 顯示員工的id,last_name,salary,部門名稱 , 要求, 把沒有部門編號的員工也給查詢到: 前置條件: 公司業務需要, 把員工編號為23 24 25 的員工 分配到了新的部門, 但是部門還未成立! update s_emp set d

ORA-00937:不是單組分組函式 ORA-22818:這裡不允許出現查詢表示式

今天,寫了以下SQL語句: select (select well_name from well where well_id = wa.well_id) well_name,sum(prod_time)/24 prod_days FROM pro_well_vol_dail

Mysql---複合查詢(多表連線、自連線、查詢(any all) from子句查詢、union)

本篇部落格對錶的操作基於以下幾個表: 首先了解下簡單查詢即對一個表的查詢: 1.員工資訊表emp mysql> select * from emp; 2.公司部門資訊表dept(部門號、部門名稱、位置) mysql> select * from dept;

09--MySQL自學教程:多表查詢之內連線、外連線以及【查詢

1.為什麼要拆表? 去除冗餘資料 2.表與表之間的關係 一對一 比如 人和身份證 QQ和QQ密碼 一對多(多對一) 比如:學生和成績的關係 多對多 比如:老師和學生的關係 3

SQL(收藏)查詢每個部門工資的員工資訊

問:Oracle的EMP表,查詢每個部門工資前三名的員工資訊,如何寫?? 解答:(通用sql) select deptno, ename, sal from emp e1 where ( select count(1) fr

mysql 查詢(四)之from後面的查詢

員工表中只有3個欄位,員工號、姓名、月薪。要完成示例1,sql為:select * from ( select empno,ename,sal from emp )員工表中沒有年薪,該怎樣完成示例2呢?select * from ( select empno,

MySQL自學筆記4--where、from、exists型查詢

MySQL自學筆記 使用MySQL 5.5以及MySQL自帶命令客戶端 子查詢 定義:一個查詢是另外一個查詢的條件時,稱為子查詢。子查詢就是在原有的查詢語句中,嵌入新的查詢,來得到想要的結果集。根據子查詢的嵌入位置,可以分為三種子查詢:where型子查

貓眼電影100(獲取圖片並記錄名字跟排名)

簡述 程式碼實現上,這個可以說是不難的。但是需要注意的是,這裡的有一些細節得注意一下。 協程的,gevent.joinall() 需要的是一個可以迭代的物件,但是內容必須是gevent.spawn

檢視每門課程成績的(分析函式)

有些公司業務需要檢視使用者消費的前幾名。比如xxx教育需要檢視每門課程成績的前兩名,這裡用到分析函式,注(只針對Db2   資料庫)具體sql如下:select * from (select  row_number()over(partition by 課程號 order b

sql語句 求每學科

select * from class a where id in (select top 2 id from class where subject= a.subject order by point desc) order by subject,point desc 這句

mysql必知必會--學習筆記(8)--查詢 where巢狀查詢語句,作為計算欄位使用查詢

1、子查詢的查詢過程一般是通過where中的in操作符來完成,in後面跟上一個子查詢,通常in之前的列名和子查詢查詢出來的列名是一致的。例如select name from book where id in (select book_id from store where s

Codeforces #208 div2思維風暴

Seryozha has a very changeable character. This time he refused to leave the room to Dima and his girlfriend (her hame is Inna, by the way). However, the

百度貼吧爬(可以指定貼吧頁碼)

百度貼吧 爬蟲 python#!/usr/bin/python # coding=utf-8 import urllib import urllib2 def loadPage(url,filename): ‘‘‘ 作用:根據URL發送請求,獲取服務器響應文件 html:返回的響應文

查詢返回的值不止一個。當查詢跟隨在 =、!=、<、<=、>、>= 之後,或查詢用作表示式時,這種情況是不允許的。”SQL查詢錯誤解析

為了實現下述程式碼,首先得有資料庫和相應的表格,本文用的是https://blog.csdn.net/qaz13177_58_/article/details/5575711/中的案例,即先用連線中那些命令建立資料庫、生成資料表,然後就有了student,teacher,course,score等表。 &n

sql查詢某個資料庫裡所有表表資訊

sql server 數表: select count(1) from sysobjects where xtype=’U’ 數檢視: select count(1) from sysobject

SQL server 查詢出現:---“查詢返回的值不止一個。當查詢跟隨在 =、!=、<、<=、>、>= 之後,或查詢用作表達式時,這種情況是不允許的。”SQL查詢錯誤解析---

gui 允許 select 查詢語句 一對一 行數 style sql 之前 最近用select進行數據篩選,碰到下面的這個錯誤: ---子查詢返回的值不止一個。當子查詢跟隨在 =、!=、<、<=、>、>= 之後,或子查詢用作表達式時,這種情況是不