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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章