1. 程式人生 > >使用union來代替欄位巢狀子查詢優化

使用union來代替欄位巢狀子查詢優化

        以前寫過一條關於任務指標的sql,這個關於查詢任務目標,任務達成情況和任務完成比例的一個查詢sql,因為查詢的任務包括了3個方面 銷售額   開卡數量和微信加粉數量的一個任務查詢 所以關聯的表比較多,最後需要做的一個結果展示效果如下:


       需要查詢出這樣的資訊,每個使用者進來可以查詢到自己的任務情況 ,我以前的做法是先使用派生表把這個任務關於自己的資訊查詢出來,再通過欄位上面使用巢狀子查詢來完成的,為了看起來直觀,語句如下:

         select 

         任務.任務名稱,

         任務.任務開始時間,

        任務.任務結束時間,

        任務.目標銷售額,

        (select sum(訂單表.結算金額) from 訂單表  left join 任務從表 on 任務從表.uid=訂單表.完成人 where 訂單表.完成人="張三")as 完成銷售額,

        (count(5)/任務.銷售額*100 )as 完成銷售比例(%),

        任務.目標開卡數,

(select count(會員表.id) from 會員表 left join 任務從表  on 會員表.業務員id=任務從表.uid where 任務從表.uid="張三")as 完成開卡數,

(count(8)/任務.目標開卡數*100)as 開卡完成比例(%),

任務.目標加粉數,

(select count(加粉中間表.會員id) from 加粉中間表 left join 任務從表 on 加粉中間表.uid="張三" ) as 完成加粉數,

(count(11)/任務.目標加粉數*100)as 加粉數完成比例(%)

from

(select 任務主表.id,任務主表.任務名稱,任務主表.任務開始時間,任務主表.結束時間,任務從表.目標銷售額,任務從表.目標開卡數,任務從表.目標加粉數 from 任務主表 left join 任務從表 on 任務主表id=任務從表.taskid) as 任務

        當時的sql就是把查詢的結果,比如銷售額的完成情況和完成的比例這些都寫在了欄位上面去進行查詢,這樣的弊端就是如果一旦資料量龐大之後,查詢效率會非常受影響,甚至會出現伺服器宕機的情況,所以考慮到以後會出現的這些情況,需要對該條語句進行優化,聽了我們組長的提示,他說可以使用union來做,最後經過思考和組長的指導,將上面的語句優化成了以下的格式:

        

由以前的橫向轉成了縱向,返回的結果可以使用list來接收,根據name的名字來做條件,計算每樣指標完成的百分比,因為再java程式裡做計算和資料庫相比,後者效率更高,特別是再資料量龐大的情況,因為某些情況計算會使索引失效而導致全表掃描 sql 如下:

select '任務名稱' as name,task.任務名稱 as value from   

(select 任務主表.id,任務主表.任務名稱,任務主表.任務開始時間,任務主表.結束時間,任務從表.目標銷售額,任務從表.目標開卡數,任務從表.目標加粉數 from 任務主表 left join 任務從表 on 任務主表id=任務從表.taskid) as task 

union  all 

select '任務開始時間' as name,task.任務開始時間 from

 (select 任務主表.id,任務主表.任務名稱,任務主表.任務開始時間,任務主表.結束時間,任務從表.目標銷售額,任務從表.目標開卡數,任務從表.目標加粉數 from 任務主表 left join 任務從表 on 任務主表id=任務從表.taskid) as task 

union all

select '目標銷售額' as name,task.目標銷售額 from

(select 任務主表.id,任務主表.任務名稱,任務主表.任務開始時間,任務主表.結束時間,任務從表.目標銷售額,任務從表.目標開卡數,任務從表.目標加粉數 from 任務主表 left join 任務從表 on 任務主表id=任務從表.taskid) as task 

union all 

select '完成銷售額' as name,sum(訂單表.結算金額) from 訂單表 left join 

 (select 任務主表.id,任務主表.任務名稱,任務主表.任務開始時間,任務主表.結束時間,任務從表.目標銷售額,任務從表.目標開卡數,任務從表.目標加粉數 from 任務主表 left join 任務從表 on 任務主表id=任務從表.taskid) as task  on 訂單表.完成人=task.uid

union all

。。。。。。(需要關聯查詢的資料)

巢狀子查詢的查詢相當於乘法,比如A表10條資料,B表10條資料,如果沒有使用索引相當於全表掃描查詢 也就是10*10的概念,而union的查詢則有點像加法,A表的查詢+B表的查詢。所以再資料量較小的情況基本沒有什麼區別 就像2+2=2*2的概念一樣而如果1000*1000和1000+1000 那樣查詢效率的結果會非常明顯。

所以有些時候也是需要根據實際情況來做調整的,但都是選擇最優,最快的方案來執行。

相關推薦

使用union代替狀子查詢優化

        以前寫過一條關於任務指標的sql,這個關於查詢任務目標,任務達成情況和任務完成比例的一個查詢sql,因為查詢的任務包括了3個方面 銷售額   開卡數量和微信加粉數量的一個任務查詢 所以關聯的表比較多,最後需要做的一個結果展示效果如下:        需要查

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

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

mysql 關於某去重查詢

 使用distinct 和 group by 對於查詢多欄位,而只對一個欄位去重是查不到正確值得,因為distinct 後面跟多欄位,mysql會對只有這些子對完全重複才能去重,而group by 查詢的欄位也只能在 group 

php mysql ajax 單表多多關鍵詞查詢

單表多欄位查詢在一些稍微複雜一點的查詢中十分有用。本文主要利用MySQL資料庫中的concat函式實現單表多欄位多關鍵詞查詢。並且顯示查詢結果的表格可根據所選資料表動態生成。 html程式碼 <!DOCTYPE html> <html> <h

SQL之CASE表示式總結之二:利用CASE語句更新的值

可以在UPDATE語句中使用CASE表示式來方便的更新欄位的值 例項:有如下工資表: 要求: (1)對目前工資為30000元以上的員工,降薪10% (2)對目前工資為25000元以上且不滿28000元的員工,加薪20% (3)上述條件以外的情形的員工,保持不變 [分析]:按照常規思路,直接對資

mysql中獲取表名&名的查詢語句

  1:查詢資料庫中所有表名  select table_name   from information_schema.tables   where table_schema='csdb' and table_type='base table';   table_schema:用於限定資料

mysql型別和查詢語句資料型別的關係

mysql欄位型別和查詢語句資料型別的關係 實驗 根據資料庫儲存的欄位型別和查詢語句中的資料型別列出下表: 資料庫 查詢語句 結果 string string ①

的引數,查詢的13個方法,但標的雙下劃線外來鍵和多對多操作

                欄位  常用欄位  AutoField() 自增列,必須填入引數 primary_key=True則成為資料庫的主鍵。無該欄位時,django自動建立 一個model不能有兩個AutoField欄位。 IntegerField() 一個整數

對於傳一個引數去資料庫裡匹配多個的資料查詢

舉個例子: <if test="customName != null and customName != ''"> and t.customName like '%'+#{customName}+'%' or t.customType = #{customName}

mysql學習筆記--狀子查詢和相關子查詢

子查詢:巢狀在其他查詢中的查詢稱之。   子查詢又稱內部,而包含子查詢的語句稱之外部查詢(又稱主查詢)。   所有的子查詢可以分為兩類,即相關子查詢和非相關子查詢   1. 非相關子查詢是獨立於外部查詢的子查詢,子查詢總共執行一次,

oracle排序為null查詢出的值在前和在後

Nulls first和nulls last是Oracle Order by支援的語法 如果Order by 中指定了表示式Nulls first則表示null值的記錄將排在最前(不管是asc 還是 desc) 如果Order by 中指定了表示式Nulls last則表示null值的記錄將排在最後

【Android效能優化】儘可能用RelativeLayout代替多層狀的LinearLayout

儘量用RelativeLayout來代替多層巢狀的LinearLayout 在Android UI開發中,有時會遇到較複雜的佈局設計,比如如下: ---------------------------------------              標題      作者             

[oracle] count()函式使用錯誤導致的查詢失敗(聚合函式聚合與分組不一致)

一 錯誤的SQL語句(原始的,格式是直接從word中拷貝的,存在多個錯誤): select to_char(t.fbsj, 'YYYY') as a, count(t.fbsj) from ( select fbsj from ods_t_ky_lw     where

java-JDBC中?佔位符的使用問題,?佔位符不可用設定名,表明等。

Class.forName(“com.mysql.jdbc.Driver”); con = DriverManager.getConnection(“jdbc:mysql://localhost:3306/selldb”,“root”,“root”); String sql = “selec

mybatis動態傳入表名,名,查詢條件進行查詢

mybatis動態傳入表名,欄位名,查詢條件進行查詢 菜鳥一枚,不足之處請多多指出 BaseMapper.xml // BaseMapper.xml <select id="findByFiled" resultType="java.util.Map" statementT

更新(狀子查詢

錯誤 UPDATE siteinfo set ORG_ID =CONCAT('0',ORG_ID) WHERE ORG_ID in (select ORG_ID from siteinfo where

OCP-1Z0-051 第142題 狀子查詢的應用

View the Exhibit and examine the structure of the PRODUCTS table. Evaluate the following query:SQL> SELECT prod_name        FROM products       WHERE pr

[慢查優化]建索引時注意選擇性 & 範圍查詢注意組合索引的順序

文章轉自:http://www.cnblogs.com/zhengyun_ustc/p/slowquery2.html 寫在前面的話: 之前曾說過“不要求每個人一定理解 聯表查詢(join/left join/inner join等)時的mysql運算過程”,但對於欄位選擇性差意味著什麼,組合索引欄位順序意味

mysql資料庫intString條件查詢

今天測試碰到個有趣的問題 很簡單一個請求 contrller裡面也很簡單 就是一個mybatis的級聯查詢,查出的資料json返回 @RequestMapping("/selectDriverCarInfolistByPartyId") public R

Java中實現對錶中多個的模糊查詢(Oracle)

public UserVO fuzzyQuery(String keyword) { UserVO user=null; ResultSet rs = null; PreparedStatement prep = null; try { String