实例测试Mysql使用索引带来的效率提升,来讨论讨

阻拦并发下的产品超卖思路是应用redis串行管理数量,但又有高产出管理多少的手艺

ServiceStack.OrmLite 笔记2

那篇主要介绍 扩大

db.Insert(new Employee { Id = 1, Name = "Employee 1" }); //默承认步

await db.InsertAsync(new Employee { Id = 1, Name = "Employee 1" }); //异步 其余的异步类似这里的那几个示例

db.InsertOnly(new Person { FirstName = "Amy" }, q => q.Insert(p => new {p.FirstName}))
// 插入部分字段 前边的参数q.Insert表示要插入的字段 生成sql: INSERT INTO "Person" ("FirstName") VALUES ('艾美')

var rowId = db.Insert(new Poco { Text = "Text" }, selectIdentity:true);// selectIdentity:true重返自增加的id

此地代码有一点点多 全局的插入时过滤 类似的有UpdateFilter ,感到正是插入时对数码实行拦阻,能够发挥您的想象,比如能够在那加日志,或然增添新的字段,交合做的事情。
public interface IAudit
{
DateTime CreatedDate { get; set; }
DateTime ModifiedDate { get; set; }
string ModifiedBy { get; set; }
}

//表对应的类
public class AuditTableA : IAudit
{
public AuditTableA()
{
this.CreatedDate = this.ModifiedDate = DateTime.UtcNow;
}

    [AutoIncrement]
    public int Id { get; set; }
    public DateTime CreatedDate { get; set; }
    public DateTime ModifiedDate { get; set; }
    public string ModifiedBy { get; set; }
}

OrmLiteConfig.InsertFilter = (dbCmd, row) => {
var auditRow = row as IAudit;
if (auditRow != null)
auditRow.CreatedDate = auditRow.ModifiedDate = DateTime.UtcNow;
};
下边是下面方法的新体位,也出自官方网站。对数据开展验证
OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = (dbCmd, row) => {
var auditRow = row as IAudit;
if (auditRow != null && auditRow.ModifiedBy == null)
throw new ArgumentNullException("ModifiedBy");
};

try
{
db.Insert(new AuditTable());
}
catch (ArgumentNullException) {
//throws ArgumentNullException
}

db.Insert(new AuditTable { ModifiedBy = "Me!" }); //succeeds

下边包车型大巴代码因为也会有insert 就也放上吧
在表被成立大概去除的时候试行sql语句
[PostCreateTable("INSERT INTO TableWithSeedData (Name) VALUES ('Foo');"

  • "INSERT INTO TableWithSeedData (Name) VALUES ('Bar');")]
    public class TableWithSeedData
    {
    [AutoIncrement]
    public int Id { get; set; }
    public string Name { get; set; }
    }

typeof(TableWithSeedData)
.AddAttributes(new PostCreateTableAttribute(
"INSERT INTO TableWithSeedData (Name) VALUES ('Foo');"
"INSERT INTO TableWithSeedData (Name) VALUES ('Bar');"));

前戏和未来,皆以可以有和睦的玩的方法
[PreCreateTable(runSqlBeforeTableCreated)][PostCreateTable(runSqlAfterTableCreated)]
[PreDropTable(runSqlBeforeTableDropped)][PostDropTable(runSqlAfterTableDropped)]
public class Table {}

Db.ExecuteSql("INSERT INTO page_stats (ref_id, fav_count) VALUES (@refId, @favCount)", new { refId, favCount }) //直接执行sql语句

Db.ExecuteSqlAsync("UPDATE page_stats SET view_count = view_count 1 WHERE id = @id", new { id })//直接奉行sql语句

创建表

前一篇忘记写创造表了,这里补上。(其实前一篇也是有那么一些)

建议设置源码里的t4模板看看效果先。

public 的质量才使得

在表被创立或然去除的时候实行sql语句
[PostCreateTable("INSERT INTO TableWithSeedData (Name) VALUES ('Foo');"

  • "INSERT INTO TableWithSeedData (Name) VALUES ('Bar');")]
    public class TableWithSeedData
    {
    [AutoIncrement]
    public int Id { get; set; }
    public string Name { get; set; }
    }

typeof(TableWithSeedData)
.AddAttributes(new PostCreateTableAttribute(
"INSERT INTO TableWithSeedData (Name) VALUES ('Foo');"
"INSERT INTO TableWithSeedData (Name) VALUES ('Bar');"));

前戏和未来,都以足以有友好的玩法
[PreCreateTable(runSqlBeforeTableCreated)][PostCreateTable(runSqlAfterTableCreated)]
[PreDropTable(runSqlBeforeTableDropped)][PostDropTable(runSqlAfterTableDropped)]
public class Table {}

public class PocoTable
{
public int Id { get; set; }

[CustomField("CHAR(20)")] //这里是数据库的类型的字段的验证,和fluentvalidation 不太一样,fluentvalidation更多是对类的字段验证。 这里的 [CustomField("CHAR(20)")]是和ef差不多,是指和数据库的映射
public string CharColumn { get; set; }

[CustomField("DECIMAL(18,4)")]
public decimal? DecimalColumn { get; set; }

}
db.CreateTable();
生成sql:
CREATE TABLE "PocoTable"
(
"Id" INTEGER PRIMARY KEY,
"CharColumn" CHAR(20) NULL,
"DecimalColumn" DECIMAL(18,4) NULL
);

//外键和引用 建议协和建多少个表,亲手撸一下。av看再多,不比约个来一发
public class TableWithAllCascadeOptions
{
[AutoIncrement] public int Id { get; set; }

[References(typeof(ForeignKeyTable1))]
public int SimpleForeignKey { get; set; }

[ForeignKey(typeof(ForeignKeyTable2), OnDelete = "CASCADE", OnUpdate = "CASCADE")]
public int? CascadeOnUpdateOrDelete { get; set; }

[ForeignKey(typeof(ForeignKeyTable3), OnDelete = "NO ACTION")]
public int? NoActionOnCascade { get; set; }

[Default(typeof(int), "17")]  //默认值
[ForeignKey(typeof(ForeignKeyTable4), OnDelete = "SET DEFAULT")]
public int SetToDefaultValueOnDelete { get; set; }

[ForeignKey(typeof(ForeignKeyTable5), OnDelete = "SET NULL")]
public int? SetToNullOnDelete { get; set; }

}

db.DropAndCreateTable();//删除然后添加表
dbFactory.Run(db => db.CreateTable(overwrite:false));//不解释 看姿势
db.CreateTable(true);// overwrite 直给

//批量增多 用工作
db.DropAndCreateTable();
var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x });
db.InsertAll(rows);

兑以后那边
internal static void InsertAll(this IDbCommand dbCmd, IEnumerable objs)
{
IDbTransaction dbTrans = null;

        try
        {
            if (dbCmd.Transaction == null)
                dbCmd.Transaction = dbTrans = dbCmd.Connection.BeginTransaction();

            var dialectProvider = dbCmd.GetDialectProvider();

            dialectProvider.PrepareParameterizedInsertStatement<T>(dbCmd);

            foreach (var obj in objs)
            {
                if (OrmLiteConfig.InsertFilter != null)
                    OrmLiteConfig.InsertFilter(dbCmd, obj);

                dialectProvider.SetParameterValues<T>(dbCmd, obj);

                try
                {
                    dbCmd.ExecNonQuery();
                }
                catch (Exception ex)
                {
                    Log.Error("SQL ERROR: {0}".Fmt(dbCmd.GetLastSqlAndParams()), ex);
                    throw;
                }
            }

            if (dbTrans != null)
                dbTrans.Commit();
        }
        finally
        {
            if (dbTrans != null)
                dbTrans.Dispose();
        }
    }

实例测量检验Mysql使用索引带来的效用进步

产品表(product) 

 

class Product

创办数据库:

{

[sql] 

  public int Id{get;set} //自增Id

CREATE DATABASE `sql_learn_db`;  

       public string Name{get;set}//产品名称

  www.2cto.com  

       public int Number{get;set}//库存

创立三个表:

       public DateTime NTime{get;set;}//仓库储存同步时间

[sql] 

       ....

Create Table: CREATE TABLE `persons` (  

}

  `Id` int(11) NOT NULL AUTO_INCREMENT,  

仓库储存更改记录表(productNumberRecord)

  `LastName` varchar(255) DEFAULT NULL,  

class productNumberRecord

  `FirstName` varchar(255) DEFAULT NULL,  

{

  `Address` varchar(255) DEFAULT NULL,  

  public int Id{get;set;}

  `City` varchar(255) DEFAULT NULL,  

       public int Number{get;set;} //此番消耗仓库储存数据

  PRIMARY KEY (`Id`)  

       public int SurplusNumber{get;set} //这一次消耗后的剩余数量

) ENGINE=InnoDB DEFAULT CHARSET=utf8  

       public DataTime Time{get;set;} //记录时间

 

       ....

表的布局: www.2cto.com  

}

[plain] 

1.将成品Id,库存存入redis,每一次操作产品仓库储存,则发出一条仓库储存的变动记录存入sql库中

----------- -------------- ------ ----- --------- ----------------  

2.此时sql库产品的实际上仓库储存应该是 仓库储存=仓库储存-仓库储存记录(大于N提姆e时间的记录)

| Field     | Type         | Null | Key | Default | Extra          |  

3.sql库中的余额,可以做定期职分按天或小时数举行共同,制止过大的记录形成select超时

----------- -------------- ------ ----- --------- ----------------  

4.假若redis挂掉,那么它将从数据库中 根据步揍2的主意一起仓库储存

| Id        | int(11)      | NO   | PRI | NULL    | auto_increment |  

 

| LastName  | varchar(255) | YES  |     | NULL    |                |  

伪代码完结(不加锁)

| FirstName | varchar(255) | YES  |     | NULL    |                |  

(最早作业){

| Address   | varchar(255) | YES  |     | NULL    |                |  

try{

| City      | varchar(255) | YES  |     | NULL    |                |  

func1(插入更换记录表);
比如func1 实施停业 直接跳出

----------- -------------- ------ ----- --------- ----------------  

func3 ...

 

func4 ...

利用JDBC插入 1000000条数据。

等任何工作

 

funcX(增减redis库存)
若果funcX实行破产,间接跳出,不插入日志

DBIndexTest.java:

假诺都工作有成 则交由业务

(请手动修改客户名和密码,并导入驱动包)

catch{
tran.callback()//事务回滚
}

[java] 

 

import java.sql.Connection;  

import java.sql.DriverManager;  

import java.sql.PreparedStatement;  

import java.sql.SQLException;  

import java.util.Random;  

  

  

public class DBIndexTest {  

  

    private static final String MYSQL_DRIVER = "com.mysql.jdbc.Driver";  

    private static final String DB_URL = "jdbc:mysql://localhost:3306/sql_learn_db";  

      

    private static final String USER_NAME = "root";  

    private static final String PASSWORD = "";  

      

    private static final String sql = "insert into persons values (null,?,?,'zjut','hangzhou')";  

      

    private static Connection conn = null;  

      

    private static PreparedStatement pstmt = null;  

      

    private static Random random = new Random();  

      

    private DBIndexTest(){};  

      

    public static String getRandomName() {  

        int fornum = 1 random.nextInt(10);  /* 1~10 */  

        StringBuilder sb = new StringBuilder();  /* 97~122 */  

        for(int i=0; i<fornum;i ) {  

            sb.append((char)(97 random.nextInt(26)));  

        }  

        return sb.toString();  

    }  

      

    private static void createConnection() {  

        try {  

            Class.forName(MYSQL_DRIVER);  

            conn = DriverManager.getConnection(DB_URL,USER_NAME,PASSWORD);  

        } catch (ClassNotFoundException e) {  

            // TODO Auto-generated catch block  

            e.printStackTrace();  

  

        } catch (SQLException e) {  

            // TODO Auto-generated catch block  

            e.printStackTrace();  

  

        }  

          

    }  

      

    public static Connection getConnection() {  

        if(conn == null) {  

            createConnection();  

        }  

        return conn;  

    }  

    public static void insertRecord() {  

        conn = getConnection();  

        try {  

            if(pstmt == null)  

                pstmt = conn.prepareStatement(sql);  

              

            pstmt.setString(1, getRandomName());  

            pstmt.setString(2, getRandomName());  

            int affect = pstmt.executeUpdate();  

            System.out.println(affect == 1 ? "插入成功!" : "插入退步!");  

              

        } catch (SQLException e) {  

            // TODO Auto-generated catch block  

            e.printStackTrace();  

        }  

    }  

      

    public static void main(String[] args) {  

        long start = System.currentTimeMillis();  

          

        for(int i=0; i< 1000000; i ) {  

            insertRecord();  

        }  

        long end = System.currentTimeMillis();  

          

        System.out.println("一共用时:" (end-start)/一千.0 "s");  

          

    }  

  

}  

 

运作结果:

[plain] 

布署成功!  

安顿成功!  

插入成功!  

...  

...  

...  

插入成功!  

安顿成功!  

布置成功!  

插入成功!  

插入成功!  

安排成功!  

布署成功!  

插入成功!  

插入成功!  

安排成功!  

安顿成功!  

插入成功!  

插入成功!  

安插成功!  

布署成功!  

插入成功!  

插入成功!  

安插成功!  

布署成功!  

总括用时:2167.19s  

 

表中已插入的记录数:

[sql] 

mysql> select count(*) from persons;  

----------  

| count(*) |  

----------  

|  1000000 |  

----------  

 

在未有对表的列LastName创设目录时,尝试查询:

 

[sql] 

mysql> select count(*) from persons where lastname='abc';  

----------  

| count(*) |  

----------  

|        7 |  

----------  

1 row in set (6.33 sec)  

 

对表列LastName创设目录:

 

[sql] 

mysql> create index my_index on persons(lastname);  

Query OK, 0 rows affected (12.44 sec)  

Records: 0  Duplicates: 0  Warnings: 0  

 

双重实施同一的询问: www.2cto.com  

 

[sql] 

mysql> select count(*) from persons where lastname='abc';  

----------  

| count(*) |  

----------  

|        7 |  

----------  

1 row in set (0.00 sec)  

 

当然,0.00 sec 不等于0,因为速度太快,单位太大(秒),四舍五入后引致该结果(换来阿秒可能就不为0了)。

何况每回实施的结果也不确定相同。不过通过那一个十分小的尝试能够看看,使用索引的表比不应用索引的表要快一些,但是并不是相对的。要不要运用索引能力要依照实际难题具体剖判。如若有些表的查询次数相当多,那么就应有扩展索引。不过索引会相应地使表更新速度下滑(因为索引也要同临时间创新)。

 

成立数据库: [sql] CREATE DATABASE `sql_learn_db`; www.2cto.com 创造贰个表: [sql] Create Table: CREATE TABLE `persons`...

本文由星彩网app下载发布于计算机编程,转载请注明出处:实例测试Mysql使用索引带来的效率提升,来讨论讨

TAG标签: 星彩网app下载
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。