SQL的优化

一个优秀的程序员不仅要鲁的一手好的代码,更要写的出一手优质的SQL语句。

下面讲讲sql究竟是如何做到优化的。

前期准备工作:

1.海量数据的生成

a.

public class DataGenerator {
private final static String PARAM_IP = "localhost"; //数据库IP地址,本机使用localhost
private final static String PARAM_USERNAME = "icbc"; //数据库用户名
private final static String PARAM_PASSWORD = "icbc";//数据库密码
private final static String PARAM_SID = "orcl";//数据库sid
private final static String PARAM_PORT = "1521"; //端口号
private final static boolean FORCE_REBUILD = true; // 建表前是否删除已经存在的对象,默认为true
private final static int ROW_COUNT = 100000; //创建数据库的条数
private Logger logger ;

public DataGenerator(){
logger = Logger.getLogger(this.getClass().getName());
}
/**
* 获取数据连接
* @return Connection 数据库连接对象
* @version 1.0
* @since 1.6.0
* @deprecated
* @see http://www.baidu.com
* @throws DBException
* 数据操作异常
*/
private Connection getConnection() throws DBException {
Connection conn = null;
String url = null;
try {
url = "jdbc:oracle:thin:@" + DataGenerator.PARAM_IP + ":"
+ DataGenerator.PARAM_PORT + ":" + DataGenerator.PARAM_SID;
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(url,
DataGenerator.PARAM_USERNAME, DataGenerator.PARAM_PASSWORD);
conn.setAutoCommit(false);
} catch (Exception e) {
throw new DBException("数据库连接[" + url + "]创建失败", e);
}
return conn;
}

/**
* 创建T_CARD_OP_LOG表
*
* @throws DBException
*/
public void createCOLTable(boolean forceRebuild) throws DBException {
try {
Connection conn = this.getConnection();
Statement stmt = conn.createStatement();
if (forceRebuild == true) {
logger.info("正在删除已存在对象");
try {
stmt.execute("drop table T_CARD_OP_LOG");
stmt.execute("drop sequence SEQ_CARD_OP_LOG");
} catch (SQLException e) {
logger.info("T_CARD_OP_LOG表不存在,忽略删除操作");
}
}

String createCOLSQL = "create table T_CARD_OP_LOG(OP_ID NUMBER(12) not null,CARD_NO VARCHAR2(19) ,OPER_NO NUMBER(4),AMT NUMBER(12,2) ,OP_DATE DATE )";
stmt.execute(createCOLSQL);
String createCOLPKSQL = "alter table T_CARD_OP_LOG add constraint PK_OP_ID primary key (OP_ID)";
stmt.execute(createCOLPKSQL);
String createCOLSeqSQL = "create sequence SEQ_CARD_OP_LOG minvalue 1 maxvalue 999999999999999999999999999 start with 1 increment by 1 cache 20";
stmt.execute(createCOLSeqSQL);
stmt.close();
conn.close();
} catch (Exception e) {
throw new DBException("T_CARD_OP_LOG表创建失败", e);
}
}

/**
* 初始化T_CARD_OP_LOG数据
*
* @throws DBException
*/
private void insertColTable() throws DBException {
try {

Connection conn = this.getConnection();
String sql = "INSERT INTO t_card_op_log(op_id , card_no , oper_no , amt , op_date) "
+ "values ([id] , ‘[cardbin][area][cardno]‘ , ‘[operno]‘ , ‘[amt]‘ , to_date(‘201405[date]‘ , ‘yyyymmdd‘))";
List<String> cardBin = new ArrayList();
// 牡丹灵通卡
cardBin.add("955880");
cardBin.add("955881");
// E时代
cardBin.add("955882");
cardBin.add("622202");
cardBin.add("622203");
// 理财金
cardBin.add("955888");

// 将CardBin数据调节成非均匀分布
for (int i = 1; i <= 30; i++) {
cardBin.add("622202");
}

List<String> areas = new ArrayList<String>();
areas.add("0402");// 石家庄
areas.add("0403");// 唐山
areas.add("0404");// 秦皇岛
areas.add("0405");// 邯郸
areas.add("0406");// 邢台
areas.add("0407");// 衡水
areas.add("0408");// 沧州
areas.add("0409");// 保定
areas.add("0410");// 廊坊
areas.add("0411");// 承德
areas.add("0412");// 张家口
// 将区域数据调节成非均匀分布
for (int i = 1; i <= 30; i++) {
areas.add("0402");
}

List<String> opno = new ArrayList();
opno.add("1314");// POS消费
opno.add("1315");// 存款
opno.add("1316");// 取款
opno.add("1317");// 转账

// 将交易数据调节成非均匀分布
for (int i = 1; i <= 30; i++) {
opno.add("1316");
}
logger.info("开始初始化T_CARD_NO_LOG数据");
for (int i = 1; i <= DataGenerator.ROW_COUNT; i++) {
int cardBinIndex = new Double((Math.random() * 100)).intValue()
% cardBin.size();
int areaIndex = new Double((Math.random() * 100)).intValue()
% areas.size();
int opnoIndex = new Double((Math.random() * 100)).intValue()
% opno.size();
String cardNo = new DecimalFormat("000000000")
.format(new Double((Math.random() * 10000)).intValue());
int amt = new Double((Math.random() * 1000000)).intValue();
int date = (new Double((Math.random() * 1000)).intValue() % 31) + 1;

String executeSQL = new String(sql);
executeSQL = executeSQL
.replace("[id]", "seq_card_op_log.nextval")
.replace("[cardbin]", cardBin.get(cardBinIndex))
.replace("[area]", areas.get(areaIndex))
.replace("[cardno]", cardNo)
.replace("[operno]", opno.get(opnoIndex))
.replace("[amt]", String.valueOf(amt))
.replace("[date]", String.valueOf(date));

Statement stmt = conn.createStatement();
stmt.execute(executeSQL);
stmt.close();
if (i % 1000 == 0) {
System.out.println("Rows : " + i);
}
}
conn.commit();
logger.info("T_CARD_NO_LOG数据初始化成功");
} catch (Exception e) {
// TODO Auto-generated catch block
throw new DBException("初始化T_CARD_OP_LOG数据失败", e);
}
}

// 初始化数据
public void init() throws DBException {
// 初始化
try {
this.createCOLTable(DataGenerator.FORCE_REBUILD);
this.insertColTable();
} catch (DBException e) {
throw e;
}
}

public static void main(String[] args) {
DataGenerator gen = new DataGenerator();
try {
gen.init();
} catch (Exception e) {
e.printStackTrace();
}
}
}

b

public class DBException extends Exception {
private DBException() {

}

public DBException(String msg, Exception e) {
super(msg, e);
}

}

文件结构

2.oracle用户的创建

3 优化

(1)select * from t_card_op_log where oper_no=‘1314‘怎么优化呢?

建立字段号的索引:

create index idx_col_operno on t_card_op_log(oper_no)

2组合索引

3函数索引

时间: 2024-11-05 20:48:23

SQL的优化的相关文章

Oracle SQL性能优化

转载自:http://www.cnblogs.com/rootq/archive/2008/11/17/1334727.html (1)      选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.如果有3个以上的表连接查询, 那就需要选择交叉表(intersection ta

SQL语句优化技术分析

摘自  http://www.cnblogs.com/wxj1020/archive/2008/04/27/1173638.html 最近几周一直在进行数据库培训,老师精湛的技术和生动的讲解使我受益匪浅.为了让更多的新手受益,我抽空把SQL语句优化部分进行了整理,希望大家一起进步. 一.操作符优化 1.IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格.但是用IN的SQL性能总是比较低的,从Oracle执行的步骤来分析用IN的SQL与不用IN的SQL有以

Mysql性能优化----SQL语句优化、索引优化、数据库结构优化、系统配置优化、服务器硬件优化

一.SQL语句优化 1-1.MySQL慢日志 1).慢日志开启方式和存储格式 如何发现有问题的SQL? 使用Mysql慢日志对有效率问题的SQL进行监控 前期准备 mysql> show variables like '%log_queri%'; +-------------------------------+-------+ | Variable_name | Value | +-------------------------------+-------+ | log_queries_no

ORACLE性能优化之SQL语句优化

版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 操作环境:AIX +11g+PLSQL 包含以下内容: 1.  SQL语句执行过程 2.  优化器及执行计划 3.  合理应用Hints 4.  索引及应用实例 5.   其他优化技术及应用 1.SQL语句执行过程 1.1 SQL语句的执行步骤 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义. 2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限. 3)视图转换,将涉及视图的查询语句转

MySQL之SQL语句优化

一 SQL语句优化的一般步骤: 1 通过show status命令了解各种SQL语句的执行频率 mysql> show status;                #show status:显示服务器状态信息 +-----------------------------------------------+-------------+ | Variable_name                                 | Value       | +---------------

SQL性能优化案例分析

这段时间做一个SQL性能优化的案例分析, 整理了一下过往的案例,发现一个比较有意思的,拿出来给大家分享. 这个项目是我在项目开展2期的时候才加入的, 之前一期是个金融内部信息门户, 里面有个功能是收集各个上市公司的财报, 然后做各种分析, 数据图表展示, 使用的人数并不多, 仅百人左右. 2期打算面向行外用户, 刚开始预计同时在线人数不超过50, 就以50访问用户/秒的性能测试, 结果在把1期的图表类数据展示响应基本在5分钟左右, 属于严重不可用, 说说我们的服务器配置, 有2台网站前端承载用户

转:sql语句优化

性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化. 为了获得稳定的执行性能,SQL语句越简单越好.对复杂的SQL语句,要设法对之进行简化. 常见的简化规则如下: 1)不要有超过5个以上的表连接(JOIN)2)考虑使用临时表或表变量存放中间结果.3)少用子查询4)视图嵌套不要过深,一般视图嵌套不要超过2个为宜. 连接的表越多,其编译的时间和连接的开销也越大,性能越不好控制. 最好是把连接拆开成较小的几个部分逐个顺序执行.

SQL语句优化原则

性能不理想的系统中除了一部分是因为应用程序的负载确实超过了服务器的实际处理能力外,更多的是因为系统存在大量的SQL语句需要优化. 为了获得稳定的执行性能,SQL语句越简单越好.对复杂的SQL语句,要设法对之进行简化. 常见的简化规则如下: 1)不要有超过5个以上的表连接(JOIN)2)考虑使用临时表或表变量存放中间结果.3)少用子查询4)视图嵌套不要过深,一般视图嵌套不要超过2个为宜. 连接的表越多,其编译的时间和连接的开销也越大,性能越不好控制. 最好是把连接拆开成较小的几个部分逐个顺序执行.

小贝_mysql sql语句优化过程

sql语句优化 一.SQL优化的一般步骤 (1).通过show status命令了解各种SQL的执行频率. (2).定位执行效率较低的SQL语句-(重点select) (3).通过explain分析低效率的SQL语句的执行情况 (4).确定问题并采取相应的优化措施 (1) 通过showstatus命令了解各种SQL的执行频率 MySQL客户端连接成功后,通过使用show[session|global] status 命令可以提供服务器状态信息.其中的session来表示当前的连接的统计结果,gl

SQL通用优化方案(where优化、索引优化、分页优化、事务优化、临时表优化)

SQL通用优化方案:1. 使用参数化查询:防止SQL注入,预编译SQL命令提高效率2. 去掉不必要的查询和搜索字段:其实在项目的实际应用中,很多查询条件是可有可无的,能从源头上避免的多余功能尽量砍掉,这是最简单粗暴的解决方案.3. 选择最有效率的表名顺序: 数据库的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表放在最后,如果有3个以上的表连接查询,那就需要选择那个被其他表所引用的表放在最后.