sql学习笔记(18)-----------数据库创建过程

手动创建数据库的步骤:

第一步:决定数据库实例的SID

数据库实例的SID用来将当前实例和以后可能创建的实例进行区分

% setenv ORACLE_SID mynewdb

第二步:建立数据库管理员认证方法

第三步:创建初始化參数文件

实例(由内存结构SAG和后台进程组成)启动过程中要读取初始化參数文件。得到初始化參数文件的一个好办法是改动一个已有的初始化參数文件。为了简化操作,将初始化參数文件放在Oracle默认的位置上。这种话。当数据库启动时,就没有必要再指定pfile參数了。由于Oracle会自己主动寻找在默认位置的初始化參数文件。

Platform                  Default Name                  Default Location

UNIX                    init$ORACLE_SID.ora          $ORACLE_HOME/dbs

Windows                  init$ORACLE_SID.ora          $ORACLE_HOME/database

假设一个数据库的名字是mynewdb,以下就是该数据库的初始化文件:

# Cache and I/O

DB_BLOCK_SIZE=4096

DB_CACHE_SIZE=20971520

# Cursors and Library Cache

CURSOR_SHARING=SIMILAR

OPEN_CURSORS=300

# Diagnostics and Statistics

BACKGROUND_DUMP_DEST=/vobs/oracle/admin/mynewdb/bdump

CORE_DUMP_DEST=/vobs/oracle/admin/mynewdb/cdump

TIMED_STATISTICS=TRUE

USER_DUMP_DEST=/vobs/oracle/admin/mynewdb/udump

# Control File Configuration

CONTROL_FILES=("/vobs/oracle/oradata/mynewdb/control01.ctl",

"/vobs/oracle/oradata/mynewdb/control02.ctl",

"/vobs/oracle/oradata/mynewdb/control03.ctl")

# Archive

LOG_ARCHIVE_DEST_1=‘LOCATION=/vobs/oracle/oradata/mynewdb/archive‘

LOG_ARCHIVE_FORMAT=%t_%s.dbf

LOG_ARCHIVE_START=TRUE

# Shared Server

# Uncomment and use first DISPATCHES parameter below when your listener is

# configured for SSL

# (listener.ora and sqlnet.ora)

# DISPATCHERS = "(PROTOCOL=TCPS)(SER=MODOSE)",

# "(PROTOCOL=TCPS)(PRE=oracle.aurora.server.SGiopServer)"

DISPATCHERS="(PROTOCOL=TCP)(SER=MODOSE)",

"(PROTOCOL=TCP)(PRE=oracle.aurora.server.SGiopServer)",

(PROTOCOL=TCP)

# Miscellaneous

COMPATIBLE=9.2.0

DB_NAME=mynewdb

# Distributed, Replication and Snapshot

DB_DOMAIN=us.oracle.com

REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE

# Network Registration

INSTANCE_NAME=mynewdb

# Pools

JAVA_POOL_SIZE=31457280

LARGE_POOL_SIZE=1048576

SHARED_POOL_SIZE=52428800

# Processes and Sessions

PROCESSES=150

# Redo Log and Recovery

FAST_START_MTTR_TARGET=300

# Resource Manager

RESOURCE_MANAGER_PLAN=SYSTEM_PLAN

# Sort, Hash Joins, Bitmap Indexes

SORT_AREA_SIZE=524288

# Automatic Undo Management

UNDO_MANAGEMENT=AUTO

UNDO_TABLESPACE=undotbs

 

第四步:连接到实例

$ SQLPLUS /nolog

CONNECT SYS/password AS SYSDBA

第五步:启动实例

不mount数据库。只启动实例。通常,不过在创建和维护数据库的时候才这样做。

STARTUP NOMOUNT

此时,数据库并不存在。仅仅有SGA和后台进程被创建。

第六步:调用create database语句

CREATE DATABASE mynewdb

USER SYS IDENTIFIED BY pz6r58

USER SYSTEM IDENTIFIED BY y1tz5p

LOGFILE GROUP 1 (‘/vobs/oracle/oradata/mynewdb/redo01.log‘) SIZE 100M,

GROUP 2 (‘/vobs/oracle/oradata/mynewdb/redo02.log‘) SIZE 100M,

GROUP 3 (‘/vobs/oracle/oradata/mynewdb/redo03.log‘) SIZE 100M

MAXLOGFILES 5

MAXLOGMEMBERS 5

MAXLOGHISTORY 1

MAXDATAFILES 100

MAXINSTANCES 1

CHARACTER SET US7ASCII

NATIONAL CHARACTER SET AL16UTF16

DATAFILE ‘/vobs/oracle/oradata/mynewdb/system01.dbf‘ SIZE 325M REUSE

EXTENT MANAGEMENT LOCAL

DEFAULT TEMPORARY TABLESPACE tempts1

DATAFILE ‘/vobs/oracle/oradata/mynewdb/temp01.dbf‘

SIZE 20M REUSE

UNDO TABLESPACE undotbs

DATAFILE ‘/vobs/oracle/oradata/mynewdb/undotbs01.dbf‘

SIZE 200M REUSE AUTOEXTEND ON NEXT 5120K MAXSIZE UNLIMITED;

数据库创建之后,数据库名称是mynewdb,它的全局数据库名是mynewdb.us.oracle.com。控制文件通过初始化參数CONTROL_FILES来创建。SYS用户的password是pz6r58,SYSTEM用户的password是y1tz5p。这两个子句在Oracle9i中是可选。可是假设设定了不论什么一个password,那么两个password都必须设定。

该数据库有三个在线重做日志组。通过LOGFILE子句来指定,MAXLOGFILES, MAXLOGMEMBERS, and MAXLOGHISTORY都是对日志文件的限制。

MAXDATAFILES指定了数据库能够打开的数据文件的最大数量,该数量会影响到控制文件的大小。在创建数据库的过程中所设定的參数,有些会受到其它因素的影响。

比方,设定了MAXDATAFILES之后,Oracle在控制文件里要分配空间存放数据文件的文件名称。即使数据库仅仅有一个数据文件。然而,由于控制文件本身也有大小的限制(跟操作系统有关)。非常有可能不能把全部CREATE
DATABASE的參数都设置为他们理论上的最大值。

MAXINSTANCES指定了仅仅有一个实例可以mount和打开数据库。US7ASCII字符集被指定为数据库保存数据使用的字符集。系统表空间由/vobs/oracle/oradata/mynewdb/system01.dbf组成,假设该文件已经存在。将会被重写。系统表空间是本地化管理的表空间。

DEFAULT_TEMPORARY_TABLESPACE子句创建并命名了一个默认的暂时表空间。UNDO_TABLESPACE子句创建并命名了一个撤销表空间。用来存储撤销记录,前提是在初始化參数文件里把UNDO_MANAGEMENT设定为AUTO。由于ARCHIVELOG子句在CREATE DATABASE语句中没有调用,因此重做日志文件并不会被归档。这是数据库创建过程的通常做法,ALTER DATABASE语句能够用来切换到ARCHIVELOG模式。

初始化文件里的LOG_ARCHIVE_DEST_1,LOG_ARCHIVE_FORMAT,
and LOG_ARCHIVE_START三个參数与归档有关。

第七步:创建额外的表空间

为了使数据局效率更高。须要创建额外的表空间和文件

CONNECT SYS/password AS SYSDBA

-- create a user tablespace to be assigned as the default tablespace for users

CREATE TABLESPACE users LOGGING

DATAFILE ‘/vobs/oracle/oradata/mynewdb/users01.dbf‘

SIZE 25M REUSE AUTOEXTEND ON NEXT 1280K MAXSIZE UNLIMITED

EXTENT MANAGEMENT LOCAL;

-- create a tablespace for indexes, separate from user tablespace

CREATE TABLESPACE indx LOGGING

DATAFILE ‘/vobs/oracle/oradata/mynewdb/indx01.dbf‘

SIZE 25M REUSE AUTOEXTEND ON NEXT 1280K MAXSIZE UNLIMITED

EXTENT MANAGEMENT LOCAL;

EXIT

第八步:创建server參数文件

Oracle建议创建一个server參数文件。作为维护初始化參数的动态方式。以下的脚本依据初始化參数文件创建了一个server初始化參数文件,并把该初始化參数文件放在默认位置。实例关闭后又一次启动时,就会使用默认位置的server初始化參数文件。

CONNECT SYS/password AS SYSDBA

-- create the server parameter file

CREATE SPFILE=‘/vobs/oracle/dbs/spfilemynewdb.ora‘ FROM

PFILE=‘/vobs/oracle/admin/mynewdb/scripts/init.ora‘;

SHUTDOWN

-- this time you will start up using the server parameter file

CONNECT SYS/password AS SYSDBA

STARTUP

EXIT

 数据库的优化

mysql表复制

复制表结构+复制表数据


1

2

mysql> createtable
t3 liket1;

mysql> insertinto
t3 select*
from t1;

mysql索引


1

2

3

4

5

6

7

8

9

10

11

12

ALTER
TABLE
用来创建普通索引、UNIQUE索引或PRIMARYKEY索引

ALTER
TABLE
table_name ADDINDEX
index_name (column_list)

ALTER
TABLE
table_name ADDUNIQUE
(column_list)

ALTER
TABLE
table_name ADDPRIMARY KEY(column_list)

Create
Index

CREATE
INDEX
index_name ONtable_name (column_list)

CREATE
UNIQUE
INDEX index_nameON
table_name (column_list)

drop
index

DROP
INDEX
index_name ONtalbe_name

alter
table
table drop

ALTER
TABLE
table_name DROPINDEX
index_name

ALTER
TABLE
table_name DROPPRIMARY
KEY

mysql视图

创建视图


1

2

mysql> createview
v_t1 asselect
* fromt1
where id>4
and id<11;

Query OK, 0
rows affected (0.00 sec)

view视图的帮助信息


1

2

3

4

mysql> ? view

ALTER
VIEW

CREATE
VIEW

DROP
VIEW

查看视图


1

mysql> show tables;

删除视图v_t1


1

mysql> dropview
v_t1;

mysql内置函数

字符串函数


1

2

3

4

5

6

7

8

9

10

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个空格

数学函数


1

2

3

4

5

6

7

BIN (decimal_number ) //十进制转二进制

CEILING (number2 ) //向上取整

FLOOR (number2 ) //向下取整

MAX(num1 ,num2) //取最大值

MIN(num1,num2) //取最小值

SQRT(number2) //开平方

RAND() //返回0-1内的随机值

日期函数


1

2

3

4

5

6

7

8

CURDATE() //返回当前日期

CURTIME() //返回当前时间

NOW() //返回当前的日期时间

UNIX_TIMESTAMP(date) //返回当前date的UNIX日间戳

FROM_UNIXTIME() //返回UNIX时间戳的日期值

WEEK(date) //返回日期date为一年中的第几周

YEAR(date) //返回日期date的年份

DATEDIFF(expr,expr2) //返回起始时间expr和结束时间expr2间天数

mysql预处理语句

设置stmt1预处理,传递一个数据作为一个where推断条件


1

mysql> preparestmt1
from ‘select * from t1 where id>?

;

设置一个变量

mysql> set @i=1;

运行stmt1预处理

mysql> execute stmt1 using @i;

设置@i为5

mysql> set @i=5;

再次去运行stmt1

mysql> execute stmt1 using @i;

怎样删除预处理stmt1

mysql> drop prepare stmt1;

mysql事务处理


1

2

3

4

5

6

7

8

9

10

11

12

13

14

--关闭自己主动提交功能

mysql> setautocommit=0;

--从表t1中删除了一条记录

mysql> deletefrom
t1 whereid=11;

--此时做一个p1还原点:

mysql> savepoint p1;

--再次从表t1中删除一条记录:

mysql> deletefrom
t1 whereid=10;

--再次做一个p2还原点:

mysql> savepoint p2;

--此时恢复到p1还原点。当然后面的p2这些还原点自己主动会失效: 

mysql> rollbackto
p1;

--退回到最原始的还原点:

mysql> rollback;

mysql存储

创建一个存储p1()


1

2

3

4

5

6

7

8

9

10

mysql> \d //

mysql> create procedure p1()

-> begin

-> set@i=0;

-> while@i<10
do

-> select@i;

-> set@[email protected]+1;

-> end while;

-> end;

-> //

运行存储p1()


1

2

3

4

5

6

mysql> \d ;

mysql> call p1();

--查看procedure p1()的status信息

mysql> show procedure status\G

--查看procedure p1()的详细信息:

mysql> show create procedure p1\G

mysql触发器


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

改动delimiter为//

mysql> \d //

创建一个名字为tg1的触发器,当向t1表中插入数据时。就向t2表中插入一条数据

  

mysql> create trigger tg1 before insert on t1for
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);

 

怎样制作删除表t1后t2表中的记录也会跟着删除呢

mysql>\d
//

mysql> create trigger tg2 beforedelete on t1for
each row 

>begin delete from t2 whereid=old.id;

>end//

mysql>\d ;

怎样制作更改表t1后t2表中的记录跟着个性呢

mysql>\d
//

mysql> create trigger tg3 beforeupdate on t1for
each row 

>begin update t2set
id=new.idwhere
id=old.id

>end//

mysql>\d ;

查看触发器

mysql> show triggers;

重排auto_increment值


1

2

3

4

5

6

7

8

9

10

11

MYSQL数据库自己主动增长的ID怎样恢复,清空表的时候。

不能用

 

delete from tablename;

而是要用:

 

truncatetable tablename;

这样auto_increment 就恢复成1了

 

或者清空内容后直接用ALTER命令改动表:

 

altertable tablename auto_increment =1;

利用GROUP BY的WITH ROLLUP


1

2

3

4

5

6

7

8

9

10

11

12

mysql> select* from demo; 

+-------+-------+ 

| cname | pname | 

+-------+-------+ 

| bj | hd | 

| bj | xc | 

| bj | hd | 

| sh | dh | 

| sh | rg | 

| sh | dh | 

+-------+-------+ 

9 rows inset
(0.00 sec)

对demo表依照cname、pname列分组对pname列进行聚合计算例如以下


1

2

3

4

5

6

7

8

9

10

11

mysql> selectcname,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 inset
(0.00 sec)

相同使用with rollupkeyword后,统计出很多其它的信息。例如以下。

注意:with rollup不能够和ordery by同一时候使用


1

2

3

4

5

6

7

8

9

10

11

12

13

14

ysql> selectcname,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 inset
(0.00 sec)

使用外键须要注意的问题

创建外键的方式


1

2

mysql>create table temp(id
int, name char(20), foreign key(id

references outTable(id) on delete cascade on update cascade)。

注意:Innodb类型的表支持外键,myisam类型的表。尽管创建外键能够成功,可是不起作用,主要原因是不支持外键。

优化SQL语句的一般步骤

通过show status命令了解各种SQL的运行频率


1

mysql> show [session|global]status;

当中:session(默认)表示当前连接,global表示自数据库启动至今


1

2

3

4

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 server已经工作的秒数

Slow_queries:慢查询的次数

定位运行效率较低的SQL语句


1

2

explain select*
from table
where id=1000;

desc
select
* fromtable
where id=1000;

通过EXPLAIN分析较低效SQL的运行计划


1

2

3

4

5

6

7

8

9

10

11

12

13

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 inset
(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个字符进行索引。这个特性能够大大缩小索引文件的大小,用户在设计表结构的时候也能够对文本列依据此特性进行灵活设计。


1

mysql>create index ind_company2_name on company2(name(4));

--当中company表名ind_company2_name索引名

MySQL怎样使用索引

1、使用索引

(1)对于创建的多列索引。仅仅要查询的条件中用到最左边的列。索引一般就会被使用。例如以下创建一个复合索引。


1

mysql>create index ind_sales2_com_mon on sales2(company_id,moneys);

然后按company_id进行查询。发现使用到了复合索引


1

mysql>explain
select * from sales2 where company_id=2006\G

使用以下的查询就没有使用到复合索引。


1

mysql>explain
select * from sales2 where moneys=1\G

(2) 使用like的查询,后面假设是常量而且仅仅有%号不在第一个字符。索引才可能会被使用。例如以下:


1

2

3

4

5

6

7

8

9

10

11

12

13

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 inset
(0.00 sec)

例如以下这个使用到了索引。而以下样例可以使用索引,差别就在于“%”的位置不同,上面的样例是吧“%”放在了第一位,而以下的样例则没有


1

2

3

4

5

6

7

8

9

10

11

12

13

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 inset
(0.00 sec)

(3)假设对大的文本进行搜索,使用全文索引而不使用like“%...%”.

(4)假设列名是索引。使用column_name is null将使用索引。例如以下


1

2

3

4

5

6

7

8

9

10

11

12

13

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 inset
(0.00 sec)

存在索引但不使用索引

(1)假设MySQL预计使用索引比全表扫描更慢,则不使用索引。比如假设列key_part1均匀分布在1到100之间,查询时使用索引就不是非常好


1

mysql>select* from table_name where key_part1>1 and key_part<90;

(2)假设使用MEMORY/HEAP表而且where条件中不使用“=”进行索引列。那么不会用到索引。Heap表仅仅有在“=”的条件下会使用索引。

(3)用or切割开的条件。假设or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。


1

2

3

4

5

6

7

mysql>show index from sales\G 

*************************** 1. row *************************** 

…… 

key_name: ind_sales_year 

seq_in_index:1 

Column_name: year 

……

从上面能够发现仅仅有year列上面有索引。

来看例如以下的运行计划。


1

2

3

4

5

6

7

8

9

10

11

12

13

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 inset
(0.00 sec)

(4)假设不是索引列的第一部分,例如以下样例:可见尽管在money上面建有复合索引,可是因为money不是索引的第一列,那么在查询中这个索引也不会被MySQL採用。


1

2

3

4

5

6

7

8

9

10

11

12

13

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 inset
(0.00 sec)

(5)假设like是以%開始。可见尽管在name上面建有索引。可是因为where 条件中like的值的“%”在第一位了,那么MySQL也会採用这个索引。

(6)假设列类型是字符串,但在查询时把一个数值型常量赋值给了一个字符型的列名name。那么尽管在name列上有索引,可是也没实用到。


1

2

3

4

5

6

7

8

9

10

11

12

13

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 inset
(0.00 sec)

而以下的sql语句就能够正确使用索引。


1

2

3

4

5

6

7

8

9

10

11

12

13

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 inset
(0.00 sec)

查看索引使用情况

假设索引正在工作。Handler_read_key的值将非常高,这个值代表了一个行被索引值读的次数。

Handler_read_rnd_next的值高则意味着查询执行低效。而且应该建立索引补救。


1

2

3

4

5

6

7

8

9

10

11

12

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 inset
(0.00 sec)

两个简单有用的优化方法

分析表的语法例如以下:(检查一个或多个表是否有错误)


1

2

3

4

5

6

7

8

9

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 inset
(0.01 sec)

优化表的语法格式:

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [,tbl_name]

假设已经删除了表的一大部分,或者假设已经对含有可变长度行的表进行了非常多的修改。则须要做定期优化。

这个命令能够将表中的空间碎片进行合并,可是此命令仅仅对MyISAM、BDB和InnoDB表起作用。

?


1

2

3

4

5

6

7

mysql> optimize table sales; 

+--------------+----------+----------+----------+ 

| Table | Op | Msg_type | Msg_text | 

+--------------+----------+----------+----------+ 

| sakila.sales | optimize | status | OK | 

+--------------+----------+----------+----------+ 

1 row inset
(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表非唯一索引:


1

2

3

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表非唯一索引:


1

2

3

4

5

6

7

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_test2enable
keys; 

Query OK,0 rows affected (12.25 sec)

--以上对MyISAM表的数据导入,但对于InnoDB表并不能提高导入数据的效率

(1)针对于InnoDB类型表数据导入的优化

由于InnoDB表的依照主键顺序保存的,所以将导入的数据主键的顺序排列,能够有效地提高导入数据的效率。

--使用test3.txt文本是按表film_test4主键存储顺序保存的


1

2

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倍)


1

2

3

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时


1

2

3

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时


1

2

3

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时


1

2

3

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时


1

2

3

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语句,这样能够大大缩短客户与数据库的连接、关闭等损耗。

能够使用insert delayed(立即运行)语句得到更高的效率。

将索引文件和数据文件分别存放不同的磁盘上。

能够添加bulk_insert_buffer_size 变量值的方法来提快速度。可是仅仅对MyISAM表使用当从一个文件里装载一个表时,使用LOAD DATA INFILE。这个通常比使用非常多insert语句要快20倍。

优化group by语句

假设查询包括group by但用户想要避免排序结果的损耗,则能够使用使用order by null来禁止排序:

例如以下没有使用order by null来禁止排序


1

2

3

4

5

6

7

8

9

10

11

12

13

mysql> explain
select id,sum(moneys) from sales2 group byid\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 inset
(0.00 sec)

例如以下使用order by null的效果:


1

2

3

4

5

6

7

8

9

10

11

12

13

mysql> explain
select id,sum(moneys) from sales2 group byid
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 inset
(0.00 sec)

优化嵌套查询

以下是採用嵌套查询的效果(能够使用更有效的链接查询(Join)替代)。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

mysql> explain
select * from sales2 where company_id notin(selectid

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 inset
(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 inset
(0.00 sec)

以下是使用更有效的链接查询(Join)


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

mysql> explain
select * from sales2 leftjoin
company2 on 

sales2.company_id = company2.idwhere 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 inset
(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 inset
(0.00 sec)

从运行计划中能够明显看出查询扫描的记录范围和使用索引的情况都有了非常大的改善。连接(JOIN)子所以更有效率一些,是由于MySQL不须要再内存中创建暂时表来完毕这个逻辑上的须要两个步骤的查询工作。

数据库优化

优化表的类型

在MySQL中,能够使用函数PROCEDUREANALYSE()对当前应用的表进行分析,改函数能够对数据表中列的数据类型提出优化建议,用户能够依据应用的实际情况酌情考虑是否实施优化。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

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.又一次生成一个新表

Mysqlserver优化

myisam读锁定

1.

lock table t1 read

2.开启还有一个mysql连接终端,接着去尝试:

select * from t1

3.再insert、update和delete t1这张表。你会发现全部的数据都停留在终端上没有真正的去操作

4.读锁定对我们在做备份大量数据时很实用.

mysqldump -uroot -p123 test >test.sql

myisam写锁定

1.

lock table t1 write

2.打开还有一个mysql终端,尝试去select、insert、update和delete这张表t1,你会发现都不能操作,都会停留在终端上。仅仅有等第一个终端操作完成,第二个终端才干真正运行.

3.可见表的写锁定比读锁定更严格

4.普通情况下我们非常少去显式的去对表进行read 和write锁定的,myisam会自己主动进行锁定的.

Mysqlserver优化

二进制日志

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%"

socket问题

mysql socket无法登录

1. 有时登录mysql时提示不能用socket登录,此时能够换成tcp方式去登录,可是能够測试时能够这样用。可是必需要在php去用之前把这个事情攻克了.


1

2

3

4

5

6

[[email protected] mysql]# mysql -uroot -pwei --protocol tcp -hlocalhost

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connectionid
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服务时产生的

rootpassword丢失

rootpassword丢失破解


1

2

3

4

5

6

7

8

9

10

11

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 [email protected]=password("wei");

6. mysql> set password=password("wei"); 

//和第五步一样,都可能成功改动password

时间: 2024-10-23 20:00:27

sql学习笔记(18)-----------数据库创建过程的相关文章

SQL学习笔记之数据库专题(二):Android下SQL数据库开发

在Android开发 中,数据库是不可缺少的.在Android开发中,用的是一种小型的嵌入式数据库,sqllite.今天会写两篇关于Android开发环境下数据库开发的文章,第一篇先介绍使用android自带的API来实现数据库的使用和管理以及增删改查.数据库升级的相关操作. 一.数据库第一次生成 1.javabean文件的准备 这里以一个Person类为例子来描述 package com.example.freedomsql.bean; import java.io.Serializable;

SQL学习笔记之数据库专题(四):浅谈JDBC用法

数据库厂商提供的用来操作数据库用的jar包就是数据库驱动.各个厂商如果提供各自的数据库驱动的话会导致开发人员学习成本太高,所以sun公司提供了一套数据库驱动应该遵循的接口规范,这套规范就叫做JDBC,本质上是很多的接口.简而言之,JDBC就是一套操作数据库的接口规范,由于所有的数据库驱动都遵循JDBC规范,我们在学习和使用数据库时只要学习JDBC中的接口就可以了. 组成JDBC的2个包:java.sql,javax.sql,开发JDBC应用需要以上2个包的支持外,还需要导入相应JDBC的数据库实

SQL学习笔记之数据库专题(一):SQL语句详解

SQL是用来存取关系数据库的语言,具有查询.操纵.定义和控制关系型数据库的四方面功能.常见的关系数据库有Oracle,SQLServer,DB2,Sybase.开源不收费的有MYSQL,SQLLite等.今天我们主要以MYSQL为例子,讲解SQL常用的SQL语句. 一.数据库 1.创建数据库 create database [if not exists] db_name [character set xxx] [collate xxx] *创建一个名称为freedom的数据库. create d

EF Code First学习笔记:数据库创建

控制数据库的位置 默认情况下,数据库是创建在localhost\SQLEXPRESS服务器上,并且默认的数据库名为命名空间+context类名,例如我们前面的BreakAway.BreakAwayContext. 有几种方法可以改变这种默认约定. 利用配置文件 在配置文件中新加一个连接字符串 <connectionStrings> <add name="BreakAwayContext" providerName="System.Data.SqlClient

SQL学习笔记——临时表不同创建方式的区别

问题:在存储过程中使用临时表时,不Create临时表就会报错. 分析了下,总结了临时表创建方式的区别. 创建临时表有两种方法: 方法一 create  table  #临时表名 ( 字段1 约束条件,      字段2 约束条件,      -- ) create  table  ##临时表名 ( 字段1 约束条件,      字段2 约束条件,      -- ) 方法二 select  *  into  #临时表名  from 你的表;   select  *  into  ##临时表名  

Laravel5.1学习笔记18 数据库4 数据填充

Introduction Writing Seeders Using Model Factories Calling Additional Seeders Running Seeders Introduction Laravel includes a simple method of seeding your database with test data using seed classes. All seed classes are stored in database/seeds. See

Oracle 学习笔记 18 -- 存储函数和存储过程(PL/SQL子程序)

PL/SQL子程序 包括函数和过程.这里的函数指的是用户自己定义的函数,和系统函数是不同的.子程序一般是完成特定功能的PL/SQL程序块,并且具有一定的通用性,可以被不同的应用程序多次调用.Oracle提供可以把PL/SQL程序存储在数据库中,并可以再任何地方来运行它.这样就叫做存储过程或者是函数.过程和函数的唯一区别就是函数总是向调用者返回数据,而过程则不返回数据. 函数 如果用户要经常执行某些操作,并且需要返回特定的数据,那么就可以将这些操作构造成一个函数. 可以使用SQL语句定义函数. 基

sqlite学习笔记2:创建数据库

在上一次笔记中最后生成了一个sqlite可执行文件,cd到sqlite所在的目录下面执行: sqlite3 MyDataBase.db 就会创建了一个名叫MyDataBase.db的数据库,在当前路径下面就会生成一个叫MyDataBase.db的文件 #切记不是先运行sqlite3,然后再上述命令,而是在终端直接输入上述命令,否则会报错:Error: near "sqlite3": syntax error 然后运行命令: .databases 可以查看刚刚创建的数据库,退出数据库命令

Oracle之PL/SQL学习笔记

自己在学习Oracle是做的笔记及实验代码记录,内容挺全的,也挺详细,发篇博文分享给需要的朋友,共有1w多字的学习笔记吧.是以前做的,一直在压箱底,今天拿出来整理了一下,给大家分享,有不足之处还望大家批评指正. PL/SQL定义:PL/SQL是由Oracle开发,专门用于Oracle的程序设计语言. PL---Procedural Language. SQL—Structure QueryLanguage.PL/SQL包括过程化语句和SQL语句     PL/SQL的单位:块. 一个块中可以嵌套