MYSQL索引類型
按邏輯來(lái)分:
1.主鍵索引
是一種特殊的唯一索引睹晒,不允許有空值
創(chuàng)建斑粱、刪除語(yǔ)句:
alter table [table_name] add primary key (column_name)
create table [table_name](
id int not null,
primary key (id)
)
alter table drop primary key
2.普通索引(單例索引)
對(duì)表中一個(gè)列進(jìn)行索引
create index index_name on [table_name] (column_name)
alter table [table_name] add index [index_name] (column_name)
alter table drop index [index_name]
3.復(fù)合索引(多列索引)
對(duì)表中多個(gè)列進(jìn)行索引
alter table [table_name] add index [index_name]
(column_name1,column_name2)
4.全文索引
可以在char凉唐、varchar或text類型的列上創(chuàng)建受葛。
alter table [table_name] add fulltext (column_name)
5.唯一索引
當(dāng)前列中的數(shù)據(jù)具有唯一性
alter table [table_name] add unique [index_name] (column_name)
在實(shí)際操作過(guò)程中开皿,應(yīng)該選取表中哪些字段作為索引锡足?
1.選擇唯一性索引
2.為經(jīng)常需要排序、分組和聯(lián)合操作的字段建立索引
3.為常作為查詢條件的字段建立索引
4.限制索引的數(shù)目
5.盡量使用數(shù)據(jù)量少的索引
6.盡量使用前綴來(lái)索引
7.刪除不再使用或者很少使用的索引
視圖作用
測(cè)試表:user有id蹬敲,name暇昂,age字段
測(cè)試表:product有id,name伴嗡,price字段
測(cè)試表:user_product有id急波,uid,pid字段
提高了重用性瘪校,就像一個(gè)函數(shù)
比如我要獲取一張用戶表和一張商品表的中用戶購(gòu)買了那個(gè)商品的信息
select * from user as u , products as p, user_product as c where u.id=c.u_id and p.id=c.p_id;
創(chuàng)建視圖
create view u_p_userage as select u.id as uid,u.name as uname,p.id as pid,p.name as pname from user as u , products as p, user_product as c where u.id=c.u_id and p.id=c.p_id
對(duì)數(shù)據(jù)庫(kù)重構(gòu)澄暮,卻不影響程序的運(yùn)行
假設(shè)我對(duì)用戶表進(jìn)行拆分,比如變成 了 id和age為一張表 id和name為一張表 那么這個(gè)時(shí)候 再去select *from user就不管用了阱扬。
那么我可以創(chuàng)建視圖 create view user as select....去重新寫sql語(yǔ)句這樣就能保證不改變腳本程序泣懊。
提高了安全性能÷榛蹋可以對(duì)不同的用戶
設(shè)定不同的視圖馍刮。例如:某用戶只能獲取user表的name和age數(shù)據(jù),不能獲取sex數(shù)據(jù)等其他數(shù)據(jù)窃蹋。
create view other as select a.name, a.age from user as a;
sql語(yǔ)句面試題:
表內(nèi)容:
2005-05-09 勝
2005-05-09 勝
2005-05-09 負(fù)
2005-05-09 負(fù)
2005-05-10 勝
2005-05-10 負(fù)
2005-05-10 負(fù)
如果要生成下列結(jié)果, 該如何寫sql語(yǔ)句?
勝 負(fù)
2005-05-09 2 2
2005-05-10 1 2
select rq,sum(case when shengfu='勝' then 1 else 0 end) as '勝',sum(case when shengfu='負(fù)' then 1 else 0 end) as'負(fù)' from tmp group by rq
表中有A B C三列,用SQL語(yǔ)句實(shí)現(xiàn):當(dāng)A列大于B列時(shí)選擇A列否則選擇B列卡啰,當(dāng)B列大于C列時(shí)選擇B列否則選擇C列。
select (case when a>b then a else b end),(case when b>c then b else c end) from table_name
請(qǐng)取出tb_send表中日期(SendTime字段)為當(dāng)天的所有記錄?(SendTime字段為datetime型警没,包含日期與時(shí)間)
select * from table_name where datediff(curdate(),SendTime)=0
有一張表匈辱,里面有3個(gè)字段:語(yǔ)文,數(shù)學(xué)杀迹,英語(yǔ)亡脸。其中有3條記錄分別表示語(yǔ)文70分,數(shù)學(xué)80分树酪,英語(yǔ)58分浅碾,請(qǐng)用一條sql語(yǔ)句查詢出這三條記錄并按以下條件顯示出來(lái)(并寫出您的思路):
大于或等于80表示優(yōu)秀,大于或等于60表示及格嗅回,小于60分表示不及格及穗。
顯示格式:
語(yǔ)文 數(shù)學(xué) 英語(yǔ)
及格 優(yōu)秀 不及格
select (case when '語(yǔ)文'>=80 then '優(yōu)秀' case when '語(yǔ)文'>=60 then ’及格‘ else '不及格' end) as '語(yǔ)文' , (case when '數(shù)學(xué)'>=80 then '優(yōu)秀' case when '數(shù)學(xué)'>=60 then ’及格‘ else '不及格' end) as '數(shù)學(xué)' ,(case when '英語(yǔ)'>=80 then '優(yōu)秀' case when '英語(yǔ)'>=60 then ’及格‘ else '不及格' end) as '英語(yǔ)' from table_name
下面附上一個(gè)習(xí)題集摧茴,大家可以去上面練習(xí)一下:
sql語(yǔ)句練習(xí)題及答案
MYSQL分頁(yè)查詢優(yōu)化
從性能最差的開(kāi)始:
select * from table_name ordered by id limit 1000,10;
但是到百萬(wàn)級(jí)數(shù)據(jù)時(shí)會(huì)變得很慢
優(yōu)化一點(diǎn)的語(yǔ)句:
SELECT * FROM table WHERE id >= (SELECT id FROM table LIMIT 1000000, 1) LIMIT 10;
因?yàn)閕d直接定位到1000000位置開(kāi)始绵载,而不用全表掃描過(guò)去。
下面這句可能更好一些:
SELECT * FROM table WHERE id BETWEEN 1000000 AND 1000010;
估計(jì)是因?yàn)闆](méi)有用子查詢,不會(huì)將結(jié)果存放在臨時(shí)表中再執(zhí)行第二步操作娃豹。between直接一步定位到1000000位置焚虱。
若查詢id并不連續(xù),使用IN的
SELECT * FROM table WHERE id IN(10000, 100000, 1000000...);
參考鏈接:
mysql視圖的作用(詳細(xì))
SQL經(jīng)典面試題及答案
MySQL 百萬(wàn)級(jí)分頁(yè)優(yōu)化(Mysql千萬(wàn)級(jí)快速分頁(yè))