T-SQL操作几个数百万行到上千万行数据的表的过程中提高效率的几点体会

最近做一个OLAP项目,要用T-SQL频繁操作几个大表,数据量大概在四、五百万到一千多万之间。这些T-SQL需要在几个小时内执行完毕。开发、测试过程遇到过几次T-SQL执行超时的情况。最慢的时候要18个小时才执行完毕。还有时候太慢了就先停止了。经过多次调整,现在整批代码大概4个小时内可以执行完毕。以下是几点重要的体会:

1:对数据库来说,写比读消耗资源高许多倍。具体多少倍当然和软硬件配置、数据库逻辑设计(表之间的关系)、数据库物理设计(索引、约束、主键等)有密切关系。在这个项目中我觉得大概有100倍。
有一步操作要把不合格的数据删除。大概会把一个500万条记录的表的数据删掉一半。删除这些数据大概要花三个小时。后来改为不删除而是仅仅做标记。显然后面用到这个表的时候会话更多的时间去搜索表和索引。但是在这个项目来看这样做是合算的。后面的步骤中的操作时间并没有明显增加。

2:通过限制数据集数量,改一步执行为循环执行的方法,可以有效提高效率。开发中遇到过几次大表之间join导致执行时间超长。最终的解决方案之一就是用row_number函数加CTE加while循环,让每一次join涉及到的记录集都比较小。虽然需要循环多次,但是最终的时间要比一次执行快了许多倍。

MySQL 字符串函数:字符串截取

MySQL 字符串函数:字符串截取

MySQL 字符串截取函数:left(), right(), substring(), substring_index()。 还有 mid(), substr()。 其中,mid(), substr() 等价于 substring() 函数,substring() 的功能非常强大和灵活。 (全文…)

MYSQL-中文检索匹配与正则表达式

今天在做mysql的一个搜索的时候发现我用 select name from contact where name like ‘%a%’的时候出来的结果除了包含a的名字外连包含中文“新”的名字也出现在搜索结果里面,这令我想弄清楚mysql的匹配模式和规则到底是怎么样的,所以决定查查资料了解了解,另外在匹配的时候正则表达式也很常用!所以准备在这里记录我学习这两个玩意的收获!
出现这个问题的原因是:MySQL在查询字符串时是大小写不敏感的,在编绎MySQL时一般以ISO-8859字符集作为默认的字符集,因此在比较过程中中文编码字符大小写转换造成了这种现象。
解决办法
1.在建表的时候对于包含中文的字段加上“BINARY”属性,使之进行二进制比较,例如讲”name char(10)”改成”name char(10) BINARY”。但是这样你对该表的该字段进行匹配的时候是区分大小写的。
2.如果使用源码编译MySQL,可以在编译的时候使用–with–charset=gbk参数,这样mysql就直接支持中文查找和排序。
3.使用mysql的locate函数来判断。如:
SELECT * FROM table WHERE locate(substr,str)>0 ;
locate()有两个形式:

LOCATE( substr , str ) ,  LOCATE(substr str , pos)

。返回substr在str中的位置,如果str不包含substr返回0。这个函数也是不区分大小写的。
4.这样使用sql语句:SELECT * FROM TABLE WHERE FIELDS LIKE BINARY ‘%FIND%’,但是这和1一样是区分大小写的如果你想进行不区分大小写的查询的时候就要使用upper或者lower进行转换。
5.使用binary和ucase函数及concat函数。ucase是讲英文全部转换大写,concat对字符串进行连接。新的sql语句如下:
select id,title,name from achech_com.news where binary ucase(title) like concat(‘%’,ucase(‘a’),’%')
也可以写为select id,title,name from achech_com.news where binary ucase(title) like ucase(‘%a%’)
检索的结果还算满意吧,不过速度可能会因此而慢N毫秒喔。 因为使用like和%进行匹配的话对效率会有一定的影响。

正则表达式:
正则表达式是为复杂搜索指定模式的强大方式。
^
所匹配的字符串以后面的字符串开头
mysql> select “fonfo” REGEXP “^fo$”; -> 0(表示不匹配)
mysql> select “fofo” REGEXP “^fo”; -> 1(表示匹配)
$
所匹配的字符串以前面的字符串结尾
mysql> select “fono” REGEXP “^fono$”; -> 1(表示匹配)
mysql> select “fono” REGEXP “^fo$”; -> 0(表示不匹配)
.
匹配任何字符(包括新行)
mysql> select “fofo” REGEXP “^f.*”; -> 1(表示匹配)
mysql> select “fonfo” REGEXP “^f.*”; -> 1(表示匹配)
a*
匹配任意多个a(包括空串)
mysql> select “Ban” REGEXP “^Ba*n”; -> 1(表示匹配)
mysql> select “Baaan” REGEXP “^Ba*n”; -> 1(表示匹配)
mysql> select “Bn” REGEXP “^Ba*n”; -> 1(表示匹配)

a+
匹配1个或多个a字符的任何序列。

mysql> select “Ban” REGEXP “^Ba+n”; -> 1(表示匹配)
mysql> select “Bn” REGEXP “^Ba+n”; -> 0(表示不匹配)

a?
匹配一个或零个a
mysql> select “Bn” REGEXP “^Ba?n”; -> 1(表示匹配)
mysql> select “Ban” REGEXP “^Ba?n”; -> 1(表示匹配)
mysql> select “Baan” REGEXP “^Ba?n”; -> 0(表示不匹配)

de|abc
匹配de或abc
mysql> select “pi” REGEXP “pi|apa”; -> 1(表示匹配)
mysql> select “axe” REGEXP “pi|apa”; -> 0(表示不匹配)
mysql> select “apa” REGEXP “pi|apa”; -> 1(表示匹配)
mysql> select “apa” REGEXP “^(pi|apa)$”; -> 1(表示匹配)
mysql> select “pi” REGEXP “^(pi|apa)$”; -> 1(表示匹配)
mysql> select “pix” REGEXP “^(pi|apa)$”; -> 0(表示不匹配)

(abc)*
匹配任意多个abc(包括空串)
mysql> select “pi” REGEXP “^(pi)*$”; -> 1(表示匹配)
mysql> select “pip” REGEXP “^(pi)*$”; -> 0(表示不匹配)
mysql> select “pipi” REGEXP “^(pi)*$”; -> 1(表示匹配)

{1} {2,3}
这是一个更全面的方法,它可以实现前面好几种保留字的功能
a*
可以写成a{0,}
a
可以写成a{1,}
a?
可以写成a{0,1}
在{}内只有一个整型参数i,表示字符只能出现i次;在{}内有一个整型参数i,
后面跟一个“,”,表示字符可以出现i次或i次以上;在{}内只有一个整型参数i,
后面跟一个“,”,再跟一个整型参数j,表示字符只能出现i次以上,j次以下
(包括i次和j次)。其中的整型参数必须大于等于0,小于等于 RE_DUP_MAX(默认是25
5)。 如果同时给定了m和n,m必须小于或等于n.

[a-dX], [^a-dX]

匹配任何是(或不是,如果使用^的话)a、b、c、d或X的字符。两个其他字符之间的“-”字符构成一个范围,与从第1个字符开始到第2个字符之间的所有字符匹配。例如,[0-9]匹配任何十进制数字 。要想包含文字字符“]”,它必须紧跟在开括号“[”之后。要想包含文字字符“-”,它必须首先或最后写入。对于[]对内未定义任何特殊含义的任何字符,仅与其本身匹配。

mysql> select “aXbc” REGEXP “[a-dXYZ]“; -> 1(表示匹配)
mysql> select “aXbc” REGEXP “^[a-dXYZ]$”; -> 0(表示不匹配)
mysql> select “aXbc” REGEXP “^[a-dXYZ] $”; -> 1(表示匹配)
mysql> select “aXbc” REGEXP “^[^a-dXYZ] $”; -> 0(表示不匹配)
mysql> select “gheis” REGEXP “^[^a-dXYZ] $”; -> 1(表示匹配)
mysql> select “gheisa” REGEXP “^[^a-dXYZ] $”; -> 0(表示不匹配)

[[.characters.]]
表示比较元素的顺序。在括号内的字符顺序是唯一的。但是括号中可以包含通配符,
所以他能匹配更多的字符。举例来说:正则表达式[[.ch.]]*c匹配chchcc的前五个字符

[=character_class=]
表示相等的类,可以代替类中其他相等的元素,包括它自己。例如,如果o和( )是
一个相等的类的成员,那么[[=o=]]、[[=( )=]]和[o( )]是完全等价的。

[:character_class:]
在括号里面,在[:和:]中间是字符类的名字,可以代表属于这个类的所有字符。
字符类的名字有: alnum、digit、punct、alpha、graph、space、blank、lower、uppe
r、cntrl、print和xdigit
mysql> select “justalnums” REGEXP “[[:alnum:]] “; -> 1(表示匹配)
mysql> select “!!” REGEXP “[[:alnum:]] “; -> 0(表示不匹配)

alnum 文字数字字符
alpha 文字字符
blank 空白字符
cntrl 控制字符
digit 数字字符
graph 图形字符
lower 小写文字字符
print 图形或空格字符
punct 标点字符
space 空格、制表符、新行、和回车
upper 大写文字字符
xdigit 十六进制数字字符

[[:<:]]
[[:>:]]
分别匹配一个单词开头和结尾的空的字符串,这个单词开头和结尾都不是包含在alnum中
的字符也不能是下划线。
mysql> select “a word a” REGEXP “[[:<:]]word[[:>:]]”; -> 1(表示匹配)
mysql> select “a xword a” REGEXP “[[:<:]]word[[:>:]]”; -> 0(表示不匹配)
mysql> select “weeknights” REGEXP “^(wee|week)(knights|nights)$”; -> 1(表示
匹配)

要想在正则表达式中使用特殊字符的文字实例,应在其前面加上2个反斜杠“\”字符。MySQL解析程序负责解释其中一个,正则表达式库负责解释另一个。例如,要想与包含特殊字符“+”的字符串“1+2”匹配,在下面的正则表达式中,只有最后一个是正确的:

mysql> SELECT '1+2' REGEXP '1+2';                       -> 0
mysql> SELECT '1+2' REGEXP '1\+2';                      -> 0
mysql> SELECT '1+2' REGEXP '1\\+2';                     -> 1

PHP 中的数据库缓存原理

本文章作者主要是用到 php 里面的数据库缓存,php缓存,cache_write,var_export功能对数据进行缓存操作了,觉得写得很不错。

如果后台应用接收到浏览器端的查询请求后,每次都与数据库连接读取数据,势必增加数据库的负担。而往往有大量的请求是重复的,我们可以把这些重复的信息采用缓存技术保存下来,重复使用,这样,在某些情况下可以大大提高程序的性能。

一、缓存函数

cache_write函数接受$string参数,写到$file文件中。注意var_export函数,作用是:

此函数返回关于传递给该函数的变量的结构信息,它和 var_dump() 类似,不同的是其返回的表示是合法的 PHP 代码。您可以通过将函数的第二个参数设置为 TRUE,从而返回变量的表示。

这些参数可以是数组或常量,而这些数组或常量通常为从数据库中取出的记录,或非序列化(unserialize)对象后得到的数据。这些都可以缓存到本地的文本文件中。

cache_write函数很简单,需要读取数据时,先判断缓存是否存在,存在的话就不去连接数据库取数据,而是直接读出缓存的文本文件,直接产生了数组或常量等类型的数据,可以直接使用。 (全文…)

mysql “group by ”与"order by"的研究--分类中最新的内容

这两天让一个数据查询难了。主要是对group by 理解的不够深入。才出现这样的情况
这种需求,我想很多人都遇到过。下面是我模拟我的内容表

我现在需要取出每个分类中最新的内容

select * from test group by category_id order by `date`

(全文…)

用PROCEDURE ANALYSE优化MYSQL表结构

PROCEDURE ANALYSE 通过分析select查询结果对现有的表的每一列给出优化的建议。
PROCEDURE ANALYSE的语法如下:

SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max_elements,[max_memory]])

max_elements (默认值256) analyze查找每一列不同值时所需关注的最大不同值的数量.
analyze还用这个值来检查优化的数据类型是否该是ENUM,如果该列的不同值的数量超过了
max_elements值ENUM就不做为建议优化的数据类型max_memory   (默认值8192) analyze查找每一列所有不同值时可能分配的最大的内存数量
 (全文...)

Mysql 数据库双机热备的配置

1。mysql数据库没有增量备份的机 制,当数据量太大的时候备份是一个很大的问题。还好mysql数据库提供了一种主从备份的机制,其实就是把主数据库的所有的数据同时写到备份数据库中。 实现mysql数据库的热备份。

2。要想实现双机的热备首先要了解主从数据库服务器的版本的需求。要实现热备mysql的版本都要高于3.2,还有一个基本的原则就是作为从数据库 的数据库版本可以高于主服务器数据库的版本,但是不可以低于主服务器的数据库版本。

3。设置主数据库服务器:

a.首先查 看主服务器的版本是否是支持热备的版本。然后查看my.cnf(类unix)或者my.ini(windows)中mysqld配置块的配置有没有 log-bin(记录数据库更改日志),因为mysql的复制机制是基于日志的复制机制,所以主服务器一定要支持更改日志才行。然后设置要写入日志的数据 库或者不要写入日志的数据库。这样只有您感兴趣的数据库的更改才写入到数据库的日志中。 (全文…)

MySql 存储过程学习

  1. 存储过程语法
    CREATE PROCEDURE proc_name([IN|OUT|INOUT] param 数据类型)
    BEGIN
    statement
    END

    在 mysql命令行下,每一个statement必须要用;(分号)隔开,分号是mysql的执行点,为了写存储过程用delimiter  // 命令将分隔符转换为//。
    delimiter //

  2. 写一个简单的procedure
    mysql-> CREATE PROCEDURE hello()
    -> BEGIN
    -> SELECT “Hello World!”;
    -> END
    -> //
  3. Query OK, 0 rows affected (0.00 sec)

  4. 调用存储过程: call proc_name
    mysql-> CALL hello()//
    +———————-+
    | it is a hello world. |
    +———————-+
    | it is a hello world. |
    +———————-+
    1 row in set (0.00 sec)
  5. 删除存储过程
    DROP proc_name
    注意:在一个存储过程中可以调用另一个存储过程,但不能删除。 (全文…)

MySQL陷内忧外患已处于消亡的边缘?

甲骨文为了在收购Sun交易中获得MySQL费尽心思,才最终获得监管机构的批准,目前来看这些努力可能是在浪费时间和金钱,人们 或将突然发现,内忧外患的MySQL已经处于消亡的边缘。在上月举行的MySQL大会上,MySQL之父迈克尔·韦德纽斯 (Michael Widenius)和大名鼎鼎的MySQL架构师布莱恩·阿克尔(Brian Aker)分别发表演讲,他们坚信任何一家公司都不可能成为MySQL开发或支持服务的唯一提供商。这些MySQL名人的做法对甲骨文来说是一种考验,将 验证甲骨文与MySQL社区配合和容忍不同意见的程度。 近日旧金山新创公司Clustrix公开宣称,自己的产品更强大更优秀,可以完成MySQL做不好的事情,可扩展至存储数十亿条数据,完全可以 取代MySQL。

Clustrix产品中不存在MySQL的 DNA,但它可以与MySQL协议互通,这样应用程序再也无需进行代码移植,它的存在无疑会伤害MySQL的付费业务。

该产品被称为针对互联网规模级应用程序的首款集群数据库系统,据说它遵循了应用程序服务器和存储系统突变成可扩展式、群集产品的进化路线。

它具有 NoSQL的key/value存储的巨大可扩容能力和高性能,而且封装在3节点服务器CLX 4010设备内的SQL具有可靠的ACID测试相关功能,该硬件设备足以处理高负荷的读/写数据操作。
(全文…)

10个可以简化开发过程的MySQL工具

使用各种精心设计的工具来管理MySQL数据库要比单纯使用传统的方法轻松得的多。开发人员应该不断寻找那些能够缩短开发时间的工具。这也是我们本 文整理这10个能够简化开发过程的MySQL工具的原因。

MySQL Workbench

MySQL Workbench是一个由MySQL开发的跨平台、可视化数据库工具。它作为DBDesigner4工程的替代应用程序而备受瞩目。MySQL Workbench可以作为windows、linux和OS X系统上的原始GUI工具,它有各种不同的版本,你可以查看下面的链接以获得它的版本信息。

MySQL Workbench版本信息

点此下载

(全文…)