MYSQL基本知识

SQL基础:

     结构化查询语言(Structured Query Language)简称SQL。使用关系模型的数据库语言。

     SQL分类:

                DDL数据定义语言:用来建表建库,修改表的

                DML数据操纵语句主要用来操作表数据

                DCL数据控制语句,数据库权限操作语句

     DML:

MYSQL语句:

   删除数据语句:DELETE

      单表删除:

      DELETE [LOW_PRIORITY 关键字延迟删除,直到没有其它客户端读取本表时再执行] [QUICK 关键词,则在删除过程中,存储引擎不会合并索引端结点,这样可以加快部分种类的删除操作的速度] [IGNORE 忽略所有的错误] FROM tbl_name [WHERE where_definition 控制语句,如果没有条件语句会删除所有行] [ORDER BY 排序] [LIMIT row_count 希望删除的行数]

      多表删除:不能在一个多表DELETE语句中使用ORDER BY或LIMIT

      DELETE [LOW_PRIORITY] [QUICK] [IGNORE] tbl_name[.删除的列] [, tbl_name[.*] ...]  FROM table1,table2,.. [WHERE where_definition 条件语句]

    

     DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name[.*] [, tbl_name[.*] ...] USING table_references [WHERE where_definition]

     快速删除表:TRUNCAT [TABLE] table_name;

       使用TRUNCATE TABLE重新设置AUTO_INCREMENT计数器,设置时不考虑是否有外键限制。

    例子:

       DELETE t1, t2 FROM t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;

       DELETE t1   from t1 where tl.id=3;

       TRUNCAT t1;

插入语句:

    1: INSERT [LOW_PRIORITY 延迟插入表 | DELAYED延迟插入表 | HIGH_PRIORITY 这么做还会导致同时进行的插入被取消] [IGNORE] [INTO] tbl_name [(col_name,...)] VALUES ({expr | DEFAULT},...),(...),.)[ ON DUPLICATE KEY UPDATE col_name=expr, ... ]


    2:表达式插入INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name SET col_name={expr | DEFAULT}, ...[ ON DUPLICATE KEY UPDATE col_name=expr, ... ]


   3:搜索插入INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [(col_name,...)] SELECT ... [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

   例子:

      INSERT INTO table (a,b,c) VALUES (1,2,3)

  INSERT INTO table (a,b,c) VALUES (1,2,

INSERT INTO table (a,b,c) VALUES (12,3)INSERT INTO table (a,b,c) VALUES (1,2

     INSERT INTO table SET a=4+5;  //表达式插入

    INSERT INTO table(a,b,c) VALUES (1,2,3),(4,5,6),......插入多个值

     INSERT INTO table SELECT * FROM table2  //从另外一个表选取数据插入

     INSERT INTO table (field1,field2,field3) SELECT field1,field2,field3 FROM table2

更新语句:

    UPDATE [LOW_PRIORITY] [IGNORE] tbl_name SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition 约束条件] [ORDER BY ... 排序] [LIMIT row_count 更新的行数]

     多表更新:

    UPDATE [LOW_PRIORITY] [IGNORE] table_references SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition 约束条件]

   例子:

     UPDATE table SET field=value WHERE id IN (...);

     UPDATE table1 ,table2 SET table1.field=table2.field WHERE table2.id=table21.id;

查询语句:

     单表查询:

        SELECT * FROM table [WHERE CONDITion]

               select * FROM emp;

         选取字段查询

           SELECT field1,field2,.. FROM table [WHERE CONDITion]

                 select ename,sal,deptno FROM emp;

          查询不重复记录:使用distinct关键字

                  select  DISTINCT deptno FROM emp;

         多条件查询:

                 select  deptno FROM emp WHERE deptno = 1;

          

        排序:ORDER BY field [DESC 倒序|ASC 正序],field2 [DESC 倒序|ASC 正序],。。。。

                   select  deptno FROM emp ORDER BY deption;

                   select  deptno FROM emp ORDER BY deption,sal DESC; //现在按照部门排序,对于统一部门按照工资排序

        现在返回条数: LIMIT [start,off]

               select  deptno FROM emp ORDER BY deption,sal DESC LIMIT 10,10;//返回十条数据

         聚合:

                      SELECT [field1,field2,..] fun_name FROM tablename [WHERE where_contition] [GROUP BY field,field2,..] [WITH ROLLUP] [HAVING wherr_contition]

                      fun_name表示要使用的聚合函数:SUM求和,MAX最大MIN最小,COUNT统计数目

                      GROUP BY 表示要进行分类(分组)聚合的字段。

                      WITH ROLLUP 是否对分类聚合后的结果再进行汇总。

                       HAVING 关键字表示对分类后的结果再进行条件过滤

                 例子:

                统计公司总人数: SELECT COUNT(*) as num FROM emp;

                统计公司各个部门人数:SELECT deptno ,COUNT(*)  as NUM FROM emp GROUP BY deptno;

                既要统计各个部门也要统计公司人数:SELECT deptno,COUNT(*) as NUM FROP emp GROUP BY deptno WITH ROLLUP;

                统计部门人数大于1的部门:SELECT deptno,COUNT(*) FROM emp GROUP BY deptno HAVING count(*) > 1;

                统计公司工资总额,最大工资,最小工资:SELECT sum(sal),max(sal),min(sal) FROM emp;

      表连接查询:

               带有 WHERE 子句的连接:

                   SELECT table1.field,table2.field,.. FROM table1,table2,... WHERE table1.field = table2.field=..

               JOIN子句连接:

                    左链接查询: 包含了所有左边表的记录甚至右表中没有和它匹配的记录。LEFT JOIN tablename,.. ON (table1.field=...);

                                LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行

                                  SELECT column_name(s) FROM table_name1 LEFT JOIN table_name2 ON table_name1.column_name=table_name2.column_name

                   右连接查询: 包含了右表中所有的记录甚至左表中没有和它匹配的记录 .RIGHT JOIN tablename,.. ON (table1.field=...);

                                RIGHT JOIN 关键字会右表 (table_name2) 那里返回所有的行,即使在左表 (table_name1) 中没有匹配的行。

                               SELECT column_name(s) FROM table_name1 RIGHT JOIN table_name2 ON table_name1.column_name=table_name2.column_nameSELECT column_name(s) FROM table_name1 LEFT JOIN table_name2 ON table_name1.column_name=table_name2.column_name

            子查询:当查询结果需要另外一条SELECT语句来支持的时就要用到子查询
子查询常用到的关键字 IN,NOT IN ,=,!=,exists,NOT exists等
记录联合:联合两个表的数据
UNION,UNION ALL
SELECT * FROM table1 UNION select * from table2;
UNION与UNION ALL的区别是:UNION去重,UNION ALL直接把结果集联合起来。
MYSQL支持的 数据类型:
数值类型:
正数类型:tinyint 占用字节 1 有符号 -128-127 无符号 0 -255
SMALLINT 2 -32768-32767 0 - 65535
MEDIUMINT 3
INT 4 -2147483648 0-4294967295
BIGINT 8
浮点数:FLOAT 4
DOUBLE 8
MYSQL使用0 填充 不满字节的数 00001;
日期和时间:
DATE 4个字节 1000-01-01 9999-12-31 年月日
DATETIME 8个字节 1000-01-01 00:00:00 9999-12-31 23:59:59 年月日时分秒
TIMESTAMP 4 UNINX时间戳 用于跟新日期为当前系统时间 返回 YYYY-MM-DD HH:MM:SS
TIME 3 -838:59:59 838:59:59
year 1 1901 2155
使用 NOW函数插入日期
          字符串类型:
char
varchar
text
longtext
binary
varbinary
ENUM枚举类型:只能单选。
CREATE table t (gender enum('M','f','g'));
SET 类型:可以选取多个成员。
                    CREATE table t (gender SET('M','f','g'));
MYSQL运算符:
算术运算符:
+,-,*,/,%
比较运算符:
=,<>或是!=,<=>,<,<=,>,>=,BETWEEN,IN,IS NULL ,IS NOT NULL,LIKE ,REGEXP或是RLIKE
例子:SELECT * FROM emp WHER ID BETWEN 10 AND 100; ID IN (value1,value2,...); id IS NULL;
逻辑运算符:
NOT或!,AND 或是 &&,OR 或是 || ,XOR
MYSQL常用函数:
字符串函数:
CANCAT(field1,field2,..) 将field1,field2,。。连接为一个字符串。
INSERT(str,x,y,instr) 将str从x开始到y结束的子字符串替换为instr
LOWER(str) 将字符串str所有字符变成小写。
UPPER(str)变为大写
LEFT(str,x)返回字符串最左的x个字符
RIGHT(str,x)
LPAD(str,n,pad)使用pad对str的最左边进行填充,直到长度为N个字符
RPAD(str,n,pad)
LTRIM(str)替换字符左边空格
RTRIM(str)
TRIM(str)
REPLACE(str,a,b)把字符str的a替换为b
STRCMP(str1,str2) 比较两个字符
SUBSTRING(str,x,y)截取字符
数值函数:
ABS(x)返回 X的绝对值。
CEIL(X) 返回大于X的最大整数
FLOOR(x)小于X的整数
MOD(x/y) 取模
日期和时间函数:
CURDATE() 当前日期
CURTIME() 当前时间
NOW() 当前日期和时间
UNINX_TIMESTAMP(date) 返回日期DATE的uninx时间戳
FROM_UNINXTIME() 返回UNINX时间戳的日期值
YEAR(date)
DATEDIFF(expr,expr2) 两个时间间隔的天数
DATE_ADD(date,interval expr type)当前日期加上一个时间间隔值。
例子: SELECT * FROM EMP WHERE datetime > NOW() AND datetime < date_add(now(),interval 31 day);
SELECT * FROM EMP WHERE datetime > NOW() AND datetime < date_add(now(),interval -31 day); //当前日期一个月前的数据
流程函数:

 


类型的选择:
表类型(存储引擎)的选择:
MYSQL 5.0 支持的存储引擎包括 NyISAM,InnoDB,BDB,MEMORY,MERGE,EXAMPLE,NDB CLuster,ARCHIVE,CSV,BLACKHOLE,FEDERATED等。
创建表的时候,如果不指定表的存储引擎,则使用默认存储引擎,修改配置文件default-table-type来设置默认引擎
show variables LIKE 'table_type';查看表的引擎
创建表的时候可以使用ENGINE关键字设置表引擎

存储引擎特性:
Myisam InnoDB MEMORY
存储限制 有 64TB 有
事物安全 不支持 支持 NOT
锁机制 表锁 行锁 表锁
B叉树索引 支持 支持 支持
哈希索引 支持
全文索引 支持
空间使用 低 高 低
内存使用 低 高 低
批量插入 高 低 高
支持外键 支持
MyIsam :
不支持事物,不支持外键,特点是访问速度快,现在插入速度也是很快,
MyIsam包含三个文件第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。 
MYiasm存储特性
静态表:固定列长的表
动态表:不固定列长的表,会产生文件碎片,如果一个MyISAM表包含任何可变长度列(VARCHAR, BLOB或TEXTDynamic), 或者如果一个表被用ROW_FORMAT=DYNAMIC选项来创建,动态存储格式被使用,OPTIMIZE table优化碎片。
       压缩表:由myisampack创建;
Innodb:支持事物机制,具有提交,回滚和崩溃恢复能力的事物安全,但是会占用更多的磁盘空间保留数据和索引。这种类型的需要使用导出工具类进行数据转义。

支持外键约束:
但要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引。
创建约束的语句
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)

    REFERENCES tbl_name (index_col_name, ...)

    [ON DELETE {RESTRICT 拒绝对父表的删除或更新操作 | CASCADE从父表删除或更新且自动删除或更新子表中匹配的行 | SET NULL从父表删除或更新行,并设置子表中的外键列为NULL | NO ACTION} NO ACTION意味这不采取动作,就是如果有一个相关的外键值在被参考的表里,删除或更新主要键值的企图不被允许进行]

    [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
创建:

CREATE TABLE parent(id INT NOT NULL,
                    PRIMARY KEY (id)
) TYPE=INNODB;
CREATE TABLE child(id INT, parent_id INT,
                   INDEX par_ind (parent_id),
                   FOREIGN KEY (parent_id) REFERENCES parent(id)
                     ON DELETE CASCADE
) TYPE=INNODB;


CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,
price DECIMAL,
PRIMARY KEY(category, id)) ENGINE=INNODB;
CREATE TABLE customer (id INT NOT NULL,
PRIMARY KEY (id)) ENGINE=INNODB;
CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,
product_category INT NOT NULL,
product_id INT NOT NULL,
customer_id INT NOT NULL,
PRIMARY KEY(no),
INDEX (product_category, product_id),
FOREIGN KEY (product_category, product_id)
REFERENCES product(category, id)
ON UPDATE CASCADE ON DELETE RESTRICT,
INDEX (customer_id),
FOREIGN KEY (customer_id)

MEMORY 存储引擎:

     存储在内存中,访问速度更快,默认使用HASH,不会对数据进行保存,一旦服务器关闭,数据全部丢失。可以用会员登录表,或是其它表。服务器需要足够的内存来维持表,所以不需要使用的时候最好是 DELETE from 或是 truncate table.

 

 

 

索引的使用:

    使用索引可以提高查询数据的速度,一般引擎支持对一个表的16个索引,总索引长度至少为256字节。MySQL支持前缀索引,及对索引字段的前N个字节创建索引,因为前N个字节如果可以区分的话不用使用整个字符作为索引减少索引长度,

   索引设计原则:

         1:搜索的索引列,不一定是所要选择的列。最适合索引的列是出现在WHERE 子句的列,或是连接子句的列,而不是出现在SELECT 关键字后的列。

         2:使用唯一索引。考虑列的值,索引的列的基数越大,索引的效果越好,如日期的列值都不同,很容易区分行,而性别的列只含有 M和F,对此列索引没多大用处,因为不管搜索那个值都会出现一般的结果。

         3:使用短索引,如果对字符串列进行索引,应该制定一个前缀长度。

         4:利用最左索引。在创建一个N列的索引的时候实际是创建了Mysql可利用的N个索引。多列索引可起几个索引的作用,因为可以使用索引最左边的列集进行匹配,右边的进行排序。

      5:不要过度使用索引。

      HASH索引:

   

 

 

索引问题:

     Mysql如何使用索引:

         对于多列索引查询条件只要使用最左边的列,一般都会使用索引。

          CREATE INDEX sal_com ON sales(company_id,moneys);

        SELECT * FROM sales WHERE company_id > 100;使用了索引

         SELECT * FROM sales WHERE moneys > 100;不使用了索引

      对于是用LIKE查询的 如果 %在字符串后面使用索引。

         SELECT* FROM sales WHERE name LIKE 'mm%';

      如果对于大文本搜索不要使用 LIKE ‘%  %’ 使用全文索引

     如果列名是索引使用 field is NULL 将使用索引

  存在索引但是不实用索引:

      1:Mysql 估计使用索引会更慢,比如数据小于10的时候

     2:使用 MEMORY/HEAP表并且不实用 = 进行索引列

     3: 用 OR分割条件 如果有任何一边没使用索引

     4:用LIKE以 %开始

    5:如果列是字符串,一定要用单引号括起来,或者不实用索引

查看索引使用情况:

    SHOW status LIKE 'Handler_read%';

 

 

Mysql视图:

          视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加 SQL 函数、WHERE 以及 JOIN 语句,我们也可以提交数据,就像这些来自于某个单一的表。但是视图是个虚拟表,并不在数据库真实存在。

         使用视图的优点:

                  简单:对与用户来说这些视图结果集都是过滤好的,不用考虑关联条件,复合条件

                   安全:使用的用户只被允许访问他们可以访问的结果集

                   数据独立:视图一经构建是和原表独立的。

              使用CREATE VIEW或ALTER VIEW创建或更改视图

              使用DROP VIEW销毁视图

              使用SHOW CREATE VIEW显示视图元数据

存储过程和函数:存储程序和函数是用CREATE PROCEDURE和CREATE FUNCTION语句创建的子程序。一个子程序要么是一个程序要么是一个函数。使用CALL语句来调用程序,程序只能用输出变量传回值。就像别其它函数调用一样,函数可以被从语句外调用(即通过引用函数名),函数能返回标量值。存储子程序也可以调用其它存储子程序。

               当一个子程序被调用时,一个隐含的USE db_name 被执行(当子程序终止时停止执行)。存储子程序内的USE语句时不允许的

                你可以使用数据库名限定子程序名。这可以被用来引用一个不在当前数据库中的子程序。比如,要引用一个与test数据库关联的存储程序p或函数f,你可以说CALL test.p()或test.f()。

                数据库移除的时候,与它关联的所有存储子程序也都被移除

               要明确地把子程序与一个给定数据库关联起来,可以在创建子程序的时候指定其名字为db_name.sp_name

               创建子程序,必须具有CREATE ROUTINE权限,并且ALTER ROUTINE和EXECUTE权限被自动授予它的创建者。如果二进制日志功能被允许,你也可能需要SUPER权限

               ALTER PROCEDURE和ALTER FUNCTION   改变存储和函数

                DROP PROCEDURE和DROP FUNCTION    删除存储和函数

                SHOW CREATE PROCEDURE和SHOW CREATE FUNCTION  查看存储和函数  SHOW CREATE FUNCTION test.hello\G

               SHOW PROCEDURE STATUS和SHOW FUNCTION STATUS

           CREATE PROCEDURE sp_name (param1,param2,...)

               [characteristic ...] routine_body

     存储过程的参数有 IN,OUT,INOUT之分而函数没有。IN 输入参数,OUT输出参数,INOUT输入输出参数

            delimiter $$ //delimiter语句用于改变 当前语句结束符   设置语句结束符为 $$

           CREATE PROCEDURE product (OUT param_id int(10) )

                 BEGIN   //begin 。。。 END  语句开始 和结束

                        SELECT COUNT(*) INTO paramid FROM t; // SELECT .. INTO  设置变量语句

                END

           CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)   // 必须设置返回变量

             RETURN CONCAT('Hello, ',s,'!');
$$

               delimiter  ;

        

call语句

       CALL语句调用一个先前用CREATE PROCEDURE创建的程序,CALL语句可以用声明为OUT或的INOUT参数的参数给它的调用者传回值。它也“返回”受影响的行数,客户端程序可以在SQL级别通过调用ROW_COUNT()函数获得这个数,从C中是调用the mysql_affected_rows() C API函数来获得

BEGIN 。。。 END语句

            存储子程序可以使用BEGIN ... END复合语句来包含多个语句。statement_list 代表一个或多个语句的列表。statement_list之内每个语句都必须用分号(;)来结尾

           复合语句可以被标记。除非begin_label存在,否则end_label不能被给出,并且如果二者都存在,他们必须是同样的

declare 变量定义语句:定义局部变量

          DECLARE仅被用在BEGIN ... END复合语句里,并且必须在复合语句的开头,在任何其它语句之前

           光标必须在声明处理程序之前被声明,并且变量和条件必须在声明光标或处理程序之前被声明

          DECLARE var_name[,...] type [DEFAULT value]

set定义变量:

       在存储程序中的SET语句是一般SET语句的扩展版本。被参考变量可能是子程序内声明的变量,或者是全局服务器变量

         SET var_name = expr [, var_name = expr]

select ... INTO变量设置语句

   select field1,field2,..  INTO param1,param2,.. FROM table limit 1;

   这个SELECT语法把选定的列直接存储到变量。因此,只有单一的行可以被取回.

流程控制语句:

       IF, CASE, LOOP, WHILE, ITERATE, 及 LEAVE 构造被完全实现,这些构造可能每个包含要么一个单独语句,要么是使用BEGIN ... END复合语句的一块语句。构造可以被嵌套

 触发器:触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。当对某一个表进行操作时如果触发了,就会自动执行,能实现数据的完整性。

         CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigger_stmt

              触发程序与命名为tbl_name的表相关。tbl_name必须引用永久性表。不能将触发程序与TEMPORARY表或视图关联起来

              trigger_time是触发程序的动作时间。它可以是BEFORE或AFTER,以指明触发程序是在激活它的语句之前或之后触发

             trigger_event指明了激活触发程序的语句的类型。trigger_event可以是下述值之一

                      INSERT:将新行插入表时激活触发程序,例如,通过INSERT、LOAD DATA和REPLACE语句

                      UPDATE:更改某一行时激活触发程序,例如,通过UPDATE语句

                      DELETE:从表中删除某一行时激活触发程序,例如,通过DELETE和REPLACE语句

            对于具有相同触发程序动作时间和事件的给定表,不能有两个触发程序。例如,对于某一表,不能有两个BEFORE UPDATE触发程序。但可以有1个BEFORE UPDATE触发程序和1个BEFORE INSERT触发程序,或1个BEFORE UPDATE触发程序和1个AFTER UPDATE触发程序

trigger_stmt是当触发程序激活时执行的语句。如果你打算执行多个语句,可使用BEGIN ... END复合语句结构

使用别名OLD和NEW,能够引用与触发程序相关的表中的列。OLD.col_name在更新或删除它之前,引用已有行中的1列。NEW.col_name在更新它之后引用将要插入的新行的1列或已有行的1列

激活触发程序时,对于触发程序引用的所有OLD和NEW列,需要具有SELECT权限,对于作为SET赋值目标的所有NEW列,需要具有UPDATE权限

DROP TRIGGER [schema_name.]trigger_name
事务 :
Mysql 通过 SET AUTOCOMMIT,START TRANSACTION,COMMIT,ROLLBACK等语句支持本地事务。
START TRANSACTION | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET AUTOCOMMIT = {0 | 1}
默认情况下Mysql自动提交(autocommit)的事务,如果需要通过明确的指令commit和rollback来提交和回滚事务,那么需要明确的食物控制命令来实习。
SET AUTOCOMMIT = 0,则所有的事务都需要自己提交。
START TRANSACTION 或是BEGIN 语句可以开始一个事务
COMMIT 和 ROLLBACK 用来提交和回滚事务
CHAIN 和 RELEASE用来定义事务提交或是回滚后的操作
CHAIN 立即开始一个新事务,RELEASE 断开和客户端的连接








常用SQL优化:
设置 DISABLE 和 ENABLE KEYS来进行大批数据导入。
ALTER TABLE tab_name DISABLE KEYS;
load data infile '' into table file_test2;
ALTER TABLE tab_name ENABLE keys;
优化GROUP By,GROUP会默认使用字段来进行排序 ,如果想显示的不使用排序,GROUP BY field ORDER BY NULL
优化ORDER BY:Mysql可以使用一个索引来满足ORDER BY而不是、需要额外的索引。WHERE条件和ORDER BY使用相同的索引,并且ORDER BY的顺序和索引顺序相同,并且ORDER BY 的字段都是升序或是降序.
EXPLAIN SELECT * FROM `youquwei_news_comment` WHERE newsid =1 ORDER BY upid ASC , dateline ASC ;
idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra  
1 SIMPLE youquwei_news_comment ref grad grad 4 const 4 Using where

             优化嵌套:

                  这个功能可以使用SELECT 语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。使用子查询可以一次性的完成很多逻辑上的多个步骤才能完成的SQl操作,同时可以避免事务或是表锁死,并且写起来也很容易,但是有些情况下使用 连接语句效率更高。

        select * FROM sales WHERE company_id NOT IN (select id from company);

       select * FROM sales left join company ON sales.company_id = company.id WHERE sales.company_id IS  null

   优化OR子句:

       如果要在OR子句使用索引那么在OR的两边条件中都要使用索引,而且不能使用复合索引,OR语句更像是 使用 分别对两边的 查询使用条件然后在 UNION

   使用SQL提示

         在表名使用 USE INDEX来确定使用那些索引

  拆分表提高访问效率:垂直分割,水平分割

         垂直分割:即把主码和一些列放到一个表,然后把主码和另外的一些的列放到另一个表。使用与一些列需要查询频繁,一些不频繁。

         水平分割:及根据一列或是多列数据的值把数据列放到两个独立的表中。

              适用与:表很大,分割后可以降低在查询时需要读的数据和索引的页数,同时也降低了索引的层数,提高了查询速度。

                         表中的数据本来就有独立性,例如表中的记录各个地区的数据或是不同时期的数据,特别是有些数据常用,有些数据不常用。

                         需要把数据存放到多个介质上。

                         如移动电话的表就可以水平分割,最近三个月的放到一个表中,其他放到另外一个表。

                          水平拆分会给应用增加复杂度,通常要查询多个表的数据,需要进行 UNION 操作。在是许多数据库应用中国这种复杂性会超过它带来的优点,水平拆分要考虑数据的增长速度。

 优化表的数据类型:使用 PROCEDURE ANALYSE()对当前表进行分析。

          SELECT * FROM TABLE PROCEDURE ANALYSE();

 使用中间表:把需要查询的数据导出到一个新表后在统计等等一些其他查询。

伱规范化:不实用数据库设计的三条准则,有时候为了数据的访问性,及降低复杂性可以不使用规范,而是产生一些数据冗余。

posted on 2015-03-30 23:30  木子牛  阅读(3541)  评论(0编辑  收藏  举报

导航