1. 程式人生 > >day39---mysql基礎三

day39---mysql基礎三

分享圖片 mit style global 固定 glob nbsp demo options

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基礎三