day39---mysql基礎三
1、索引:
字典得目錄,便於數據查找。
原理:將列信息存儲在其相關的文件,這些信息使用便於檢索的方式如B-tree、哈希來存儲
索引的分類:
普通所有:name,只能幫助查找
唯一索引:name,幫助查找,約束內容不能重復,null,
也可做聯合唯一索引
主鍵索引:與唯一索引類似,但不允許null,一張表只能有一個主鍵
支持聯合主鍵
組合索引:多列公共組成索引
普通多列索引(name,email):用處不大
聯合唯一索引(name,email):有用
全文索引:類似對長的字段做了一個分詞的操作,對中文支持不好。
常用:solr ,lucence,sphix來做全文搜索
2、創建索引:
*普通索引:加快查找速度
驗證:使用命令explain 若type 是all表示全表搜索,若為ref 表示通過索引搜索
*唯一索引:關鍵詞unique
type =const ,查找效率高
*聯合索引:索引最左原則,
單獨使用右邊的並不啟用索引
3、正確的使用索引:
@*like ‘%xx’ 不走索引 like ‘xx%’走索引
@*使用函數 : select coun(1) from tb2 where reverse(name) = ‘xxx‘ 不走索引,select coun(1) from tb2 where name = reverse(‘xxx‘) 走索引
@*or : select * from tb1 where nid = 1 or email = ‘xxxx‘ ,nid email都有索引才走索引
@*類型不一致:select * from tb1 where name = ‘xxxx‘ 會走索引,select * from tb1 where name = 111 不走索引
@*!= 和 > : 不走索引,特殊的 若該列為主鍵則走索引,否則不走索引;;;;;其他比較的走索引
@*orderby: select email from tb1 order by name desc 不走索引; select name form tb1 order by name desc 走索引
@*組合索引最左側走索引,eg(name,email) name and email 走索引,name 走索引,email 不走索引
覆蓋索引:所有數據都拿到叫做覆蓋索引
索引合並:2個單個索引一起使用叫做索引合並
組合索引:2列做成一個索引
4、小知識:在加上limit後可在沒有索引的時候可能會快速的完成查詢
5、mysql 使用註意實現:
? 避免使用select *
? count(1) or count(列) 代替count(*)
? 創建表時盡量使用char代替varchar
? 表得字段順序固定長度的字段優先
? 組合索引代替多個單列索引(經查使用多個條件查詢時)
? 盡量使用短索引(否則會導致產生超大索引文件,方法在創建索引時列名標長度)
? 使用連接(join)來代替子查詢(sub-Quries)
? 連表時註意條件類型要一致
? 索引散列值(重復少)不做索引,例:性別不適合
? 適度創建索引,不要過度創建
? 大批量導入導出數據時可先刪除索引而後在添加索引以提高效率
6、分頁的最佳方案:
select * from tb limit 200000,5;
第一種優化方案:
select * from tb1 where nid > (select nid from tb1 limit 200000,1 ) limit 5
此方案效率不高
第二種優化方案:
每頁顯示10條數據,供1000條
a. 上一頁,下一頁(使用應用傳過來的nid值)
select * from tb1 where nid <9989 order by nid desc limit 10;
b. 上一頁,100 99 98 97 96 95 94 下一頁
select * from tb1 where nid <9989 order by nid desc limit 10;
#9989 ... 9959
select nid form (select nid from tb1 where nid < 9989 order by nid desc limit 40) as A order by nid asc limit 1 ;
select * from tb1 where nid < 動態最新id order by nid desc limit 10;
7、執行計劃:
語法:explain + 查詢SQL
id 表示查詢個數 ,id大的先執行
8、慢查詢:
*配置文件(win):win my-default.ini
slow_query_log = off
long_query_time = 2
slow_query_log_file = /xxxxx/log
log_queries_not_using_indexes = off -- 記錄沒有使用索引的查詢
查看當前配置信息:
show GLOBAL VARIABLES like ‘%query%‘
設置:
set global slow_query_log = on;
set global long_query_time =1 ;
set global log_queries_not_using_indexes = on
*查看mysql慢日誌
eg: mysqldumpslow
-s at 需要我們關註
r 反序 a 顯示全部值 g 匹配符合正則的結果 l 總時間不顯示鎖定時間
9、SQLAlchemy
SQLAlchemy 是python 下的一個ORM框架
SQLAlchemy 本身無法操作數據庫,必須依靠pymysql等第三插件,Dialect擁有和數據api進行交流,依據配置文件得不同調用不同得數據api從而實現對數據庫得操作。
1)底層處理
eg:
MySQL-Python
mysql+mysqldb://<
user
>:<
password
>@<host>[:<port>]/<dbname>
pymysql
mysql+pymysql://<username>:<
password
>@<host>/<dbname>[?<options>]
MySQL-Connector
mysql+mysqlconnector://<
user
>:<
password
>@<host>[:<port>]/<dbname>
cx_Oracle
oracle+cx_oracle://
user
:pass@host:port/dbname[?
key
=value&
key
=value...]
更多詳見:http://docs.sqlalchemy.org/en/latest/dialects/
index
.html
#!/usr/bin/env python # -*- coding:utf-8 -*- import pymysql # 創建連接 conn = pymysql.connect(host=‘10.10.8.12‘, port=3306, user=‘sysadmin‘, passwd=‘password01!‘, db=‘q2‘) # 創建遊標 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 執行SQL,並返回收影響行數 # effect_row = cursor.execute("UPDATE users set name = ‘john1‘") effect_row = cursor.execute("insert into users(name,password) VALUES (‘john33‘,‘123.123‘)") conn.commit() #cursor.lastrowid 可獲取自增列的id print(cursor.lastrowid) # u = input("pls input username>>>>") # p = input("pls input passwd>>>>>>") # effect_row = cursor.execute("insert into users(name,password) VALUES (%s,%s)",(u,p)) #批量插入數據: # effect_row = cursor.executemany("insert into users(name,password) VALUES (%s,%s)", # [(‘john3‘,‘john3333‘),(‘john5‘,‘john555‘)]) # print(effect_row) # 提交,不然無法保存新建或者修改的數據 # conn.commit() #查詢數據 # # effect_row = cursor.execute("select * from users") # effect_row = cursor.execute(‘select * from users where nid > %s ORDER BY nid DESC ‘,(5,)) # #fetchall--- 拿到所有的數據, fetchone 第一次執行拿到第一個數據,第二次執行拿到第二個數據, # #cursor.scroll(2, mode=‘relative‘)可用來移動遊標 # # # result = cursor.fetchall() # # print(result) # result = cursor.fetchone() # print(result) # result = cursor.fetchone() # print(result) # #遊標的移動,mode="relative"相對移動,mode=‘absolute‘絕對移動 # # cursor.scroll(-1, mode=‘relative‘) # # cursor.scroll(2, mode=‘relative‘) # cursor.scroll(0, mode=‘absolute‘) # result = cursor.fetchone() # print(result) # 關閉遊標 cursor.close() # 關閉連接 conn.close()coding demo
day39---mysql基礎三