mysql表複製 php
複製表結構+複製表數據前端
mysql> create table t3 like t1; mysql> insert into t3 select * from t1;
mysql索引 mysql
ALTER TABLE table_name ADD INDEX index_name (column_list) ALTER TABLE table_name ADD UNIQUE (column_list) ALTER TABLE table_name ADDPRIMARY KEY (column_list)
CREATE INDEX index_name ON table_name (column_list) CREATE UNIQUE INDEX index_name ON table_name (column_list)
DROP INDEX index_name ON talbe_name
ALTER TABLE table_name DROP INDEX index_name ALTER TABLE table_name DROP PRIMARY KEY
mysql視圖 sql
mysql> create view v_t1 as select * from t1 where id>4 and id<11; Query OK, 0 rows affected (0.00 sec)
mysql> ? view ALTER VIEW CREATE VIEW DROP VIEW
mysql> show tables;
mysql> drop view v_t1;
mysql內置函數 數據庫
CONCAT (string2 [,… ]) //鏈接字串 LCASE (string2 ) //轉換成小寫 UCASE (string2 ) //轉換成大寫 LENGTH (string ) //string長度 LTRIM (string2 ) //去除前端空格 RTRIM (string2 ) //去除後端空格 REPEAT (string2 ,count ) //重複count次 REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替換search_str SUBSTRING (str , position [,length ]) //從str的position開始,取length個字符 SPACE(count) //生成count個空格
BIN (decimal_number ) //十進制轉二進制 CEILING (number2 ) //向上取整 FLOOR (number2 ) //向下取整 MAX(num1 ,num2) //取最大值 MIN(num1,num2) //取最小值 SQRT(number2) //開平方 RAND() //返回0-1內的隨機值
CURDATE() //返回當前日期 CURTIME() //返回當前時間 NOW() //返回當前的日期時間 UNIX_TIMESTAMP(date) //返回當前date的UNIX日間戳 FROM_UNIXTIME() //返回UNIX時間戳的日期值 WEEK(date) //返回日期date爲一年中的第幾周 YEAR(date) //返回日期date的年份 DATEDIFF(expr,expr2) //返回起始時間expr和結束時間expr2間天數
mysql預處理語句 後端
mysql> prepare stmt1 from 'select * from t1 where id>?';
mysql> set @i=1;
mysql> execute stmt1 using @i;
mysql> set @i=5;
mysql> execute stmt1 using @i;
mysql> drop prepare stmt1;
mysql事務處理 服務器
--關閉自動提交功能 mysql> set autocommit=0; --從表t1中刪除了一條記錄 mysql> delete from t1 where id=11; --此時作一個p1還原點: mysql> savepoint p1; --再次從表t1中刪除一條記錄: mysql> delete from t1 where id=10; --再次作一個p2還原點: mysql> savepoint p2; --此時恢復到p1還原點,固然後面的p2這些還原點自動會失效: mysql> rollback to p1; --退回到最原始的還原點: mysql> rollback ;
mysql存儲 session
mysql> \d // mysql> create procedure p1() -> begin -> set @i=0; -> while @i<10 do -> select @i; -> set @i=@i+1; -> end while; -> end; -> //
mysql> \d ; mysql> call p1(); --查看procedure p1()的status信息 mysql> show procedure status\G --查看procedure p1()的具體信息: mysql> show create procedure p1\G
mysql觸發器 socket
mysql> \d //
mysql> create trigger tg1 before insert on t1 for each ro >begin >insert into t2(id) values(new.id); >end// --準備兩個空表t1和t2 mysql> select * from t1; mysql> select * from t2; --向t1表中插入多條數據: mysql> insert into t1 values(1),(2),(3),(4);
mysql>\d // mysql> create trigger tg2 beforedelete on t1 for each row >begin delete from t2 where id=old.id; >end// mysql>\d ;
mysql>\d // mysql> create trigger tg3 beforeupdate on t1 for each row >begin update t2 set id=new.id where id=old.id; >end// mysql>\d ;
mysql> show triggers;
重排auto_increment值 tcp
MYSQL數據庫自動增加的ID如何恢復,清空表的時候。不能用
delete from tablename;
而是要用:
truncatetable tablename;
這樣auto_increment 就恢復成1了
或者清空內容後直接用ALTER命令修改表:
altertable tablename auto_increment =1;
利用GROUP BY的WITH ROLLUP
mysql> select * from demo; +-------+-------+ | cname | pname | +-------+-------+ | bj | hd | | bj | xc | | bj | hd | | sh | dh | | sh | rg | | sh | dh | +-------+-------+ 9 rows in set (0.00 sec)
mysql> select cname,pname,count(pname) from demo group by cname,pname; +-------+-------+--------------+ | cname | pname | count(pname) | +-------+-------+--------------+ | bj | hd | 3 | | bj | xc | 2 | | sh | dh | 3 | | sh | rg | 1 | +-------+-------+--------------+ 4 rows in set (0.00 sec)
ysql> select cname,pname,count(pname) from demo group by cname,pname with rollup; +-------+-------+--------------+ | cname | pname | count(pname) | +-------+-------+--------------+ | bj | hd | 3 | | bj | xc | 2 | | bj | NULL | 5 | | sh | dh | 3 | | sh | rg | 1 | | sh | NULL | 4 | | NULL | NULL | 9 | +-------+-------+--------------+ 7 rows in set (0.00 sec)
使用外鍵須要注意的問題
mysql>create table temp( id int, name char(20), foreign key(id) references outTable(id) on delete cascade on update cascade);
注意:Innodb類型的表支持外鍵,myisam類型的表,雖然建立外鍵能夠成功,可是不起做用,主要緣由是不支持外鍵。
優化SQL語句的通常步驟
mysql> show [session|global]status;
其中:session(默認)表示當前鏈接,global表示自數據庫啓動至今
mysql>show status; mysql>show global status; mysql>show status like ‘Com_%’; mysql>show global status like ‘Com_%’;
參數說明:
Com_XXX表示每一個XXX語句執行的次數如:
Com_select 執行select操做的次數,一次查詢只累計加1
Com_update 執行update操做的次數
Com_insert 執行insert操做的次數,對批量插入只算一次。
Com_delete 執行delete操做的次數
只針對於InnoDB存儲引擎的:
InnoDB_rows_read 執行select操做的次數
InnoDB_rows_updated 執行update操做的次數
InnoDB_rows_inserted 執行insert操做的次數
InnoDB_rows_deleted 執行delete操做的次數
其餘:
connections 鏈接mysql的數量
Uptime 服務器已經工做的秒數
Slow_queries:慢查詢的次數
explain select * from table where id=1000; desc select * from table where id=1000;
mysql> explain select count(*) from stu where name like "a%"\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: stu type: range possible_keys: name,ind_stu_name key: name key_len: 50 ref: NULL rows: 8 Extra: Using where; Using index 1 row in set (0.00 sec)
每一列的簡單解釋
id: 1 select_type: SIMPLE 表示select的類型,常見的取值有SIMPLE()簡單表,即不使用錶鏈接或者子查詢)、PRIMARY(主查詢,即外層的查詢)、UNION(UNION中的第二個或者後面的查詢語句)、SUBQUERY(子查詢中的第一個SESECT)等 table: stu 輸出結果集的表 type: range 表示表的鏈接類型,性能有好到差:system(表僅一行)、const(只一行匹配)、eq_ref(對於前面的每一行使用主鍵和惟一)、ref(同eq_ref,但沒有使用主鍵和惟一)、ref_or_null(同前面對null查詢)、index_merge(索引合併優化)、unique_subquery(主鍵子查詢)、index_subquery(非主鍵子查詢)、range(表單中的範圍查詢)、index(都經過查詢索引來獲得數據)、all(經過全表掃描獲得的數據) possible_keys: name,ind_stu_name 表查詢時可能使用的索引。 key: name 表示實際使用的索引。 key_len: 50 索引字段的長度 ref: NULL rows: 8 掃描行的數量 Extra: Using where; Using index 執行狀況的說明和描述
索引問題
MyISAM存儲引擎的表的數據和索引是自動分開存儲的,各自是獨一的一個文件;InnoDB存儲引擎的表的數據和索引是存儲在同一個表空間裏面,但能夠有多個文件組成。MySQL目前不支持函數索引,可是能對列的前面某一部分進行索引,例如name字段,能夠只取name的前4個字符進行索引,這個特性能夠大大縮小索引文件的大小,用戶在設計表結構的時候也能夠對文本列根據此特性進行靈活設計。
mysql>create index ind_company2_name on company2(name(4)); --其中company表名ind_company2_name索引名
一、使用索引
(1)對於建立的多列索引,只要查詢的條件中用到最左邊的列,索引通常就會被使用。以下建立一個複合索引。
mysql>create index ind_sales2_com_mon on sales2(company_id,moneys);
而後按company_id進行查詢,發現使用到了複合索引
mysql>explain select * from sales2 where company_id=2006\G
使用下面的查詢就沒有使用到複合索引。
mysql>explain select * from sales2 where moneys=1\G
(2) 使用like的查詢,後面若是是常量而且只有%號不在第一個字符,索引纔可能會被使用,以下:
mysql> explain select * from company2 where name like "%3"\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: company2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set (0.00 sec)
以下這個使用到了索引,而下面例子可以使用索引,區別就在於「%」的位置不一樣,上面的例子是吧「%」放在了第一位,而下面的例子則沒有
mysql> explain select * from company2 where name like "3%"\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: company2 type: range possible_keys: ind_company2_name key: ind_company2_name key_len: 11 ref: NULL rows: 103 Extra: Using where 1 row in set (0.00 sec)
(3)若是對大的文本進行搜索,使用全文索引而不使用like「%...%」.
(4)若是列名是索引,使用column_name is null將使用索引。以下
mysql> explain select * from company2 where name is null\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: company2 type: ref possible_keys: ind_company2_name key: ind_company2_name key_len: 11 ref: const rows: 1 Extra: Using where 1 row in set (0.00 sec)
(1)若是MySQL估計使用索引比全表掃描更慢,則不使用索引。例如若是列key_part1均勻分佈在1到100之間,查詢時使用索引就不是很好
mysql>select * from table_name where key_part1>1 and key_part<90;
(2)若是使用MEMORY/HEAP表而且where條件中不使用「=」進行索引列,那麼不會用到索引。Heap表只有在「=」的條件下會使用索引。
(3)用or分割開的條件,若是or前的條件中的列有索引,然後面的列中沒有索引,那麼涉及的索引都不會被用到。
mysql>show index from sales\G *************************** 1. row *************************** …… key_name: ind_sales_year seq_in_index:1 Column_name: year ……
從上面能夠發現只有year列上面有索引。來看以下的執行計劃。
mysql> explain select * from sales where year=2001 or country=‘China’\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales type: ALL possible_keys: ind_sales_year key: NULL key_len: NULL ref: NULL rows: 12 Extra: Using where 1 row in set (0.00 sec)
(4)若是不是索引列的第一部分,以下例子:可見雖然在money上面建有複合索引,可是因爲money不是索引的第一列,那麼在查詢中這個索引也不會被MySQL採用。
mysql> explain select * from sales2 where moneys=1 \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set (0.00 sec)
(5)若是like是以%開始,可見雖然在name上面建有索引,可是因爲where 條件中like的值的「%」在第一位了,那麼MySQL也會採用這個索引。
(6)若是列類型是字符串,但在查詢時把一個數值型常量賦值給了一個字符型的列名name,那麼雖然在name列上有索引,可是也沒有用到。
mysql> explain select * from company2 where name name=294\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: company2 type: ALL possible_keys: ind_company2_name key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set (0.00 sec)
而下面的sql語句就能夠正確使用索引。
mysql> explain select * from company2 where name name=‘294’\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: company2 type: ref possible_keys: ind_company2_name key: ind_company2_name key_len: 23 ref: const rows: 1 Extra: Using where 1 row in set (0.00 sec)
若是索引正在工做,Handler_read_key的值將很高,這個值表明了一個行被索引值讀的次數。
Handler_read_rnd_next的值高則意味着查詢運行低效,而且應該創建索引補救。
mysql> show status like 'Handler_read%'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | Handler_read_first | 0 | | Handler_read_key | 5 | | Handler_read_next | 0 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 2055 | +-----------------------+-------+ 6 rows in set (0.00 sec)
兩個簡單實用的優化方法
mysql> CHECK TABLE tbl_name[,tbl_name] …[option] …option = { QUICK | FAST | MEDIUM| EXTENDED | CHANGED} mysql> check table sales; +--------------+-------+----------+----------+ | Table | Op | Msg_type | Msg_text | +--------------+-------+----------+----------+ | sakila.sales | check | status | OK | +--------------+-------+----------+----------+ 1 row in set (0.01 sec)
優化表的語法格式:
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [,tbl_name]
若是已經刪除了表的一大部分,或者若是已經對含有可變長度行的表進行了不少的改動,則須要作按期優化。這個命令能夠將表中的空間碎片進行合併,可是此命令只對MyISAM、BDB和InnoDB表起做用。
mysql> optimize table sales; +--------------+----------+----------+----------+ | Table | Op | Msg_type | Msg_text | +--------------+----------+----------+----------+ | sakila.sales | optimize | status | OK | +--------------+----------+----------+----------+ 1 row in set (0.05 sec)
經常使用SQL的優化
當用load命令導入數據的時候,適當設置能夠提升導入的速度。
對於MyISAM存儲引擎的表,能夠經過如下方式快速的導入大量的數據。
ALTER TABLE tbl_name DISABLE KEYS loading the data ALTER TABLE tbl_name ENABLE KEYS
DISABLE KEYS 和ENABLE KEYS 用來打開或關閉MyISAM表非惟一索引的更新,能夠提升速度,注意:對InnoDB表無效。
--沒有使用打開或關閉MyISAM表非惟一索引: mysql> load data infile ‘/home/mysql/film_test.txt’into table film_test2; Query OK,529056 rows affected (1 min 55.12 sec) Records:529056 Deleted:0 Skipped:0 Warnings:0 --使用打開或關閉MyISAM表非惟一索引: mysql> alter table film_test2 disable keys; Query OK,0 rows affected (0.0 sec) mysql> load data infile ‘/home/mysql/film_test.txt’into table film_test2; Query OK,529056 rows affected (6.34 sec) Records:529056 Deleted:0 Skipped:0 Warnings:0 mysql> alter table film_test2 enable keys; Query OK,0 rows affected (12.25 sec) --以上對MyISAM表的數據導入,但對於InnoDB表並不能提升導入數據的效率
(1)針對於InnoDB類型表數據導入的優化
由於InnoDB表的按照主鍵順序保存的,因此將導入的數據主鍵的順序排列,能夠有效地提升導入數據的效率。
--使用test3.txt文本是按表film_test4主鍵存儲順序保存的 mysql> load data infile ‘/home/mysql/film_test3.txt’into table film_test4; Query OK, 1587168 rows affected (22.92 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0 --使用test3.txt沒有任何順序的文本(效率慢了1.12倍) mysql> load data infile ‘/home/mysql/film_test4.txt’into table film_test4; Query OK, 1587168 rows affected (31.16 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0
(2)關閉惟一性效驗能夠提升導入效率
在導入數據前先執行set unique_checks=0,關閉惟一性效驗,在導入結束後執行set unique_checks=1,恢復惟一性效驗,能夠提升導入效率。
--當unique_checks=1時 mysql> load data infile ‘/home/mysql/film_test3.txt’into table film_test4; Query OK,1587168 rows affected (22.92 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0 --當unique_checks=0時 mysql> load data infile ‘/home/mysql/film_test3.txt’into table film_test4; Query OK,1587168 rows affected (19.92 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0
(3)關閉自動提交能夠提升導入效率
在導入數據前先執行set autocommit=0,關閉自動提交事務,在導入結束後執行set autocommit=1,恢復自動提交,能夠提升導入效率。
--當autocommit=1時 mysql> load data infile ‘/home/mysql/film_test3.txt’into table film_test4; Query OK,1587168 rows affected (22.92 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0 --當autocommit=0時 mysql> load data infile ‘/home/mysql/film_test3.txt’into table film_test4; Query OK,1587168 rows affected (20.87 sec) Records:1587168 Deleted:0 Skipped:0 Warnings:0
儘可能使用多個值表的insert語句,這樣能夠大大縮短客戶與數據庫的鏈接、關閉等損耗。
可使用insert delayed(立刻執行)語句獲得更高的效率。
將索引文件和數據文件分別存放不一樣的磁盤上。
能夠增長bulk_insert_buffer_size 變量值的方法來提升速度,可是隻對MyISAM表使用當從一個文件中裝載一個表時,使用LOAD DATA INFILE。這個一般比使用不少insert語句要快20倍。
若是查詢包含group by但用戶想要避免排序結果的損耗,則可使用使用order by null來禁止排序:
以下沒有使用order by null來禁止排序
mysql> explain select id,sum(moneys) from sales2 group by id\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using temporary;Using filesort 1 row in set (0.00 sec)
以下使用order by null的效果:
mysql> explain select id,sum(moneys) from sales2 group by id order by null\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using temporary 1 row in set (0.00 sec)
下面是採用嵌套查詢的效果(可使用更有效的連接查詢(Join)替代)。
mysql> explain select * from sales2 where company_id not in(select id from company2)\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1000 Extra: Using where 1 row in set (0.00 sec)
*************************** 2. row *************************** id: 2 select_type: SIMPLE table: company2 type: index_subquery possible_keys: ind_company2_id key: ind_company2_id key_len: 5 ref: func rows: 2 Extra: Using index 1 row in set (0.00 sec)
下面是使用更有效的連接查詢(Join)
mysql> explain select * from sales2 left join company2 on sales2.company_id = company2.id where sales2.company_id is null\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: sales2 type: ALL possible_keys: ind_sales2_companyid_moneys key: ind_sales2_companyid_moneys key_len: 5 ref: count rows: 1 Extra: Using where 1 row in set (0.00 sec) *************************** 2. row *************************** id: 2 select_type: SIMPLE table: company2 type: index_subquery possible_keys: ind_company2_id key: ind_company2_id key_len: 5 ref: func rows: 1 Extra: 1 row in set (0.00 sec)
從執行計劃中能夠明顯看出查詢掃描的記錄範圍和使用索引的狀況都有了很大的改善。鏈接(JOIN)子因此更有效率一些,是由於MySQL不須要再內存中建立臨時表來完成這個邏輯上的須要兩個步驟的查詢工做。
數據庫優化
在MySQL中,可使用函數PROCEDUREANALYSE()對當前應用的表進行分析,改函數能夠對數據表中列的數據類型提出優化建議,用戶能夠根據應用的實際狀況酌情考慮是否實施優化。
mysql> select * from duck_cust procedure analyse()\G *************************** 1. row *************************** Field_name: sakila.duch_cust.cust_num Min_value: 1 Max_value: 6 Min_length: 1 Max_length: 1 Empties_or_zeros: 0 Nulls: 0 Avg_value_or_avg_length: 3.5000 Std: 1.7078 Optimal_fieldtype: ENUM(‘1’,‘2’,‘3’,‘4’) NOT NULL *************************** 2. row *************************** ……
1.分庫分表
2.分區
主要目的:
1.減小表的記錄數
2.減少對操做系統的負擔壓力
中間表的產生:
1.view 視圖
2.從新生成一個新表
Mysql服務器優化
1.
lock table t1 read
2.開啓另外一個mysql鏈接終端,接着去嘗試:
select * from t1
3.再insert、update和delete t1這張表,你會發現全部的數據都停留在終端上沒有真正的去操做
4.讀鎖定對咱們在作備份大量數據時很是有用.
mysqldump -uroot -p123 test >test.sql
1.
lock table t1 write
2.打開另外一個mysql終端,嘗試去select、insert、update和delete這張表t1,你會發現都不能操做,都會停留在終端上,只有等第一個終端操做完畢,第二個終端才能真正執行.
3.可見表的寫鎖定比讀鎖定更嚴格
4.通常狀況下咱們不多去顯式的去對錶進行read 和write鎖定的,myisam會自動進行鎖定的.
Mysql服務器優化
1.log-bin=mysql-bin
查看bin-log日誌:
mysql> show binary logs;
查看最後一個bin-log日誌:
mysql> show master status;
開戶和設置慢查詢時間:
vi /etc/my.cnf
log_slow_queries=slow.log long_query_time=5
慢查詢次數:
mysql> show global status like "%quer%"
mysql socket沒法登陸
1. 有時登陸mysql時提示不能用socket登陸,此時能夠換成tcp方式去登陸,可是能夠測試時能夠這樣用,可是必需要在php去用以前把這個事情解決了.
[root@localhost mysql]# mysql -uroot -pwei --protocol tcp -hlocalhost Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 34 Server version: 5.0.77-log Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>
這樣就能夠登陸,這樣就不用mysql.sock來登陸,而mysql.sock是啓動mysqld服務時產生的
root密碼丟失破解 1.service mysqld stop 2. mysqld_safe --skip-grant-tables --user=mysql & //跳過受權表mysql.user和mysql.db這些表 3. mysql -uroot 4. set password=password("wei"); //用這一條語句結果報錯,就是由於加了--skip-grant-tables 4. mysql>update user set password=password("wei") where user='root' and host='localhost'; 5. mysql> set password for root@localhost=password("wei"); 6. mysql> set password=password("wei"); //和第五步同樣,均可能成功修改密碼
我是天王蓋地虎的分割線