1. 程式人生 > >MySQL開發技巧

MySQL開發技巧

參考:

1、 MySQL開發技巧

2、 MySQL開發技巧2

3、MySQL開發技巧3

 

常見的SQL語句型別

DDL:資料定義語言

TPL:事務處理語言

DCL:資料控制語言

DML:資料操作語言(CRUD)

如何正確的使用Join從句

 

 

內連線 INNER
全外連線(不支援) FULL OUTER
左外連線 LEFT OUTER
右外連線 RIGHT OUTER
交叉連線(又稱笛卡爾積) CROSS

全外連線(FULL OUTER)實現方式:

SELECT A.*,B.* FROM table A LEFT JOIN table B ON B.Key = A.Key

UNION ALL

SELECT A.*,B.* FROM table B RIGNT JOIN table A ON A.Key = B.Key

使用JOIN更新表

UPDATE table A

JOIN table B ON A.key = B.key

SET A.column=set_value;

使用JOIN優化子查詢

準備表:

CREATE TABLE `users` (
  `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(20) NOT NULL,
  `password` varchar(32) NOT NULL,
  `age` tinyint(3) unsigned NOT NULL DEFAULT '10',
  `sex` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8

CREATE TABLE `province` (
  `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `pname` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8

 

第1種子查詢:

select A.id,A.username,(select pname from  province B WHERE A.username=B.pname) as pname from users A;

show profiles; 

第2種外連線查詢;

select A.id,A.username,B.pname from users A left join province B on A.username=B.pname;

show profiles;

所以第2種比較好。

 

使用join優化聚合子查詢

如何實現分組選擇

查詢每人打怪最多的兩條記錄;

方法1:

WITH tmp AS(

    SELECT a.user_name,b.timestr,b.kills, ROW_NUMBER() over(partition by a.user_name order by b.kills) cnt

    FROM user1 a

JOIN user_kills b ON a.id = b.user_id

)select * from tmp where cnt <=2;

方法2:

SELECT d.user_name,c.timestr,kills

FROM(

    SELECT user_id,timestr,kills,( SELECT COUNT(*) FROM user_kills b WHERE b.user_id = a.user_id AND a.kills <=b.kills) AS cnt

FROM user kills a

GROUP BY user_id,timestr,kills

)c

JOIN user1 d ON c.user_id = d.id

WHERE cnt <=2;

 

 

檢視mysql語句執行時間

1. Show profiles是5.0.37之後新增的,要想使用此功能,要確保版本在5.0.37之後。

 

2.確定支援show profile 後,檢視profile是否開啟,資料庫預設是不開啟的。變數profiling是使用者變數,每次都得重新啟用。

   檢視方法: show variables like "%pro%";

   設定開啟方法: set profiling = 1;

   再次檢視show variables like "%pro%"; 已經是開啟的狀態了。

3.可以開始執行一些想要分析的sql語句了,執行完後,show profiles; 即可檢視所有sql的總的執行時間。

show profile for query 1 即可檢視第1個sql語句的執行的各個操作的耗時詳情。

 

 

 

 show profile cpu, block io, memory,swaps,context switches,source for query 6;可以查看出一條SQL語句執行的各種資源消耗情況,比如CPU,IO等

 show profile all for query 6 檢視第6條語句的所有的執行資訊。

 測試完畢後,關閉引數:

mysql> set profiling=0

方法二: timestampdiff來檢視執行時間。

這種方法有一點要注意,就是三條sql語句要儘量連一起執行,不然誤差太大,根本不準

set @d=now();
select * from comment;
select timestampdiff(second,@d,now());

如果是用命令列來執行的話,有一點要注意,就是在select timestampdiff(second,@d,now());後面,一定要多copy一個空行,不然最後一個sql要你自己按回車執行,這樣就不準了。

行轉列

場景:

1、報表統計

2、彙總顯示

set names 'gbk';

 

mysql> select a.user_name,sum(kills)
    -> from user1 a
    -> join user_kills b on a.id =b.user_id
    -> group by a.user_name;
+-----------+------------+
| user_name | sum(kills) |
+-----------+------------+
| 孫悟空          |         47 |
| 沙僧        |          9 |
| 豬八戒         |         24 |
+-----------+------------+
3 rows in set (0.01 sec)

--方法1:
select * 
from(
  select  sum(kills) as '沙僧' from user1 a join user_kills b on a.id =b.user_id and a.user_name='沙僧'
  ) a
cross join(
  select  sum(kills) as '豬八戒' from user1 a join user_kills b on a.id =b.user_id and a.user_name='豬八戒'
  ) b
cross join(
  select  sum(kills) as '孫悟空' from user1 a join user_kills b on a.id =b.user_id and a.user_name='孫悟空'
  ) c 
;
--方法2:
select sum(case when user_name='孫悟空' then kills end) as '孫悟空'
,sum(case when user_name='豬八戒' then kills end) as '豬八戒'
,sum(case when user_name='沙僧' then kills end) as '沙僧'
from user1 a
join user_kills b on a.id = b.user_id
;

mysql> select *
    -> from(
    ->   select  sum(kills) as '沙僧' from user1 a join user_kills b on a.id =b.user_id and a.user_n
ame='沙僧'
    ->   ) a
    -> cross join(
    ->   select  sum(kills) as '豬八戒' from user1 a join user_kills b on a.id =b.user_id and a.user
_name='豬八戒'
    ->   ) b
    -> cross join(
    ->   select  sum(kills) as '孫悟空' from user1 a join user_kills b on a.id =b.user_id and a.user
_name='孫悟空'
    ->   ) c
    -> ;
+------+--------+--------+
| 沙僧   | 豬八戒      | 孫悟空       |
+------+--------+--------+
|    9 |     24 |     47 |
+------+--------+--------+
1 row in set (0.01 sec) 


mysql> select sum(case when user_name='孫悟空' then kills end) as '孫悟空'
    -> ,sum(case when user_name='豬八戒' then kills end) as '豬八戒'
    -> ,sum(case when user_name='沙僧' then kills end) as '沙僧'
    -> from user1 a
    -> join user_kills b on a.id = b.user_id
    -> ;
+--------+--------+------+
| 孫悟空       | 豬八戒      | 沙僧   |
+--------+--------+------+
|     47 |     24 |    9 |
+--------+--------+------+
1 row in set (0.00 sec)


 

列轉行