// todomysql
InnoDB:支持事物、在線熱備份、行鎖
MyISAM:支持全文索引、地理空間索引算法
索引是幫助MySQL高效獲取數據的數據結構,因此索引本質上是一種數據結構
create indexsql
CREATE INDEX index_name ON table_name (column_list)
alter table數據庫
ALTER TABLE `table_name` ADD INDEX index_name (column_list)
以articles的type字段爲例安全
-- 建立索引 CREATE INDEX idx_type ON articles (type); -- 刪除索引 drop index idx_type on articles -- 查看索引 show index from articles
通常狀況下,在where或join子句中出現的列須要添加索引。可是,由於MySQL只對<
,<=
,=
,>
,>=
,between
,in
,以及某些時候的like纔會使用索引(使用like時,以通配符%
和_
查詢時,MySQL不會使用索引)性能優化
哪些狀況下須要建立索引服務器
哪些狀況下不須要建立索引數據結構
給維度高的列建立索引併發
年齡
維度就高於性別
使用短索引數據庫設計
索引列排序
獨立的列
在查詢時,索引不能是表達式的一部分,也不能是函數的參數,不然沒法使用索引
前綴索引
對於blob,text,varchar類型的列,必須使用前綴索引,只索引開始的部分字符
多列索引
在須要使用多個列做爲條件查詢時,使用多列索引比使用單列索引性能要好
索引列的順序
在寫查詢語句時,將選擇性強的列放在前面
left join是由左邊決定的,左邊必定都有,因此右邊是咱們的關鍵點,創建索引要建右邊的。固然若是索引在左邊,能夠用右鏈接。
儘量減小Join語句中的NestedLoop的循環次數:「永遠用小結果集驅動大的結果集」
where條件的列=
的判斷放在比較運算符>
、<
等的左邊,放在比較運算符右邊的索引會失效
好比:
select * from user where username="saboran" and age > 18 and mobile = "18862612345"
其中username、age、mobile都有索引,可是隻有username和age的索引會生效,mobile索引用不到
select *
操做,用須要的字段代替*
!=
或者<>
的時候沒法使用索引,會致使全表掃描like 以通配符開頭,mysql索引會失效變成全表掃描
因此最好用右邊通配符匹配like 'tssk%'
若是要使用兩邊通配符匹配,則將like條件放在最後一個
好比:
select age from users where a = 3 and b = 4 and c like "%abcd%";
這樣a、b、c都有索引的話,a、b用的上,c用不上
用來分析SQL語句,分析結果中比較重要的字段有:
慢查詢主要是由於訪問了過多數據,除了訪問過多行以外,也包括訪問了過多列。最好不要使用select *
語句,要根據須要選擇查詢的列
最好使用limit
語句取出想要的那些行,還能夠創建索引來減小條件語句的全表掃描
ABS(x) // 返回x的絕對值
select abs(age) from users limit 1; -- 18
BIN(x) // 返回x的二進制數
select bin(age) from users limit 1; -- 10010
CEILING(x) // 返回大於x的最小整數值
SELECT CEILING (19.1) ; -- 20
FLOOR(x) // 返回小於x的最大值
SELECT floor (19.1) ; -- 19
RAND() // 返回0到1的隨機數
SELECT rand() ; -- 0.8320153586864615 隨機數
ROUND(x,y) // 返回參數x的四捨五入的y位小數值
SELECT ROUND(100.123456,3); -- 100.123
AVG(col) // 返回指定列的平均數
select avg(age) from users ; -- 14.0000
COUNT(col) // 返回指定列中非null值的個數
SELECT count(id) from users ; -- 2
MIN(col) // 返回指定列的最小值
select min(age) from users ; -- 10
MAX(colcol) // 返回指定列的最大值
select max(age) from users ; -- 18
SUM(col) // 返回指定列全部值的和
select sum(age) from users ; -- 28
GROUP_CONCAT(col) // 返回由屬於一組的列值鏈接組合而成的結果
select GROUP_CONCAT(age) from users ; -- 18,20
CONCAT(s1,s2,s3,sn) // 將s1,s2,s3,sn鏈接爲字符串
select CONCAT(id,age,name) from users limit 1; -- 118安小下
CONCAT_WS('|') // 將s1,s2,s3,sn鏈接爲字符串,並使用|
分隔,|
能夠替換爲任意分隔符
SELECT CONCAT_WS('|',id,name,age) from users limit 1; -- 1|安小下|18
CURDATE()/CURRENT_DATE() // 返回當前日期
SELECT CURRENT_DATE(); -- 2018-03-08
CURTIME()/CURRENT_TIME() // 返回當前時間
SELECT CURRENT_TIME(); -- 08:54:15
DATE_FORMAT(date,fmt) // 按照fmt格式,格式化date
SELECT DATE_FORMAT(CURRENT_DATE(),'%Y/%m/%d'); -- 2018/03/08
DAYOFWEEK(date) // 返回date爲一週以內的第幾天,從0開始,0表明第一天
SELECT DAYOFWEEK(CURRENT_DATE()); -- 5
DAYOFMONTH(date) // 返回date爲一月以內的第幾天
SELECT DAYOFMONTH(CURRENT_DATE()); -- 8
DAYOFYEAR(date) // 返回date爲一年以內的第幾天
SELECT DAYOFYEAR(CURRENT_DATE()); -- 67
DAYNAME(date) // 返回date的星期名
SELECT DAYNAME(CURRENT_DATE()); -- Thursday
FROM_UNIXTIME(timestimps,fmt) // 時間戳轉成fmt格式的字符串時間
SELECT FROM_UNIXTIME(1520500384,"%Y/%m/%d"); -- 2018/03/08
HOUR(time) // 返回time的小時值(0-23)
SELECT HOUR('20:10'); -- 20
MINUTE(time) // 返回time的分鐘值(0-59)
SELECT HOUR('20:10'); -- 10
MONTH(date) // 返回date的月份值(1-12)
SELECT MONTH(CURRENT_DATE()); -- 3
MONTHNAME(date) // 返回date的月份名
SELECT MONTHNAME(CURRENT_DATE()); -- March
NOW() // 獲取當前日期和時間
SELECT NOW(); -- 2018-03-08 09:26:55
WEEK(date) // 返回日期date爲一年中的第幾周
SELECT WEEK(CURDATE()); -- 9
YEAR(date) // 返回日期date的年份
SELECT YEAR(CURDATE()); -- 2018
// todo
單獨的distinct只能放在開頭
-- 會報錯 select id,DISTINCT(name) from test; -- 不會報錯 select DISTINCT(name) from test;