我正在做一些测试,看看我是否可以将CockroachDB用于我的一个小项目。我在同一个DC中创建了两个相同的VPS,并在其中一个上安装了CockroachDB,另一个安装了MariaDB,然后创建了两个测试数据库来存储数据。每次以5K的批量执行1M插入。 我没有对VPS / db服务器进行任何更改,它们只是在安装后运行。
CockroachDB架构:
root@:26257/test> show create table customers;
+-----------+------------------------------------------------------------------+
| Table | CreateTable
|
+-----------+------------------------------------------------------------------+
| customers | CREATE TABLE customers (
|
| | id INT NOT NULL DEFAULT unique_rowid(),
|
| | first_name STRING NULL,
|
| | last_name STRING NULL,
|
| | age INT NULL,
|
| | CONSTRAINT "primary" PRIMARY KEY (id ASC),
|
| | FAMILY "primary" (id, first_name, last_name, age) |
| | )
|
+-----------+------------------------------------------------------------------+
MariaDB的:
MariaDB [test]> show create table customers \G;
*************************** 1. row ***************************
Table: customers
Create Table: CREATE TABLE `customers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(250) DEFAULT NULL,
`last_name` varchar(250) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7000001 DEFAULT CHARSET=latin1
插入脚本非常愚蠢,只需快速拼凑起来就可以使用golang将一堆数据插入到数据库中(对于CockroachDB和MariaDB来说,它们的差异很小,即:连接字符串):
package main
import "database/sql"
import _ "github.com/lib/pq"
import "fmt"
import "strings"
import "math/rand"
import "time"
func init() {
rand.Seed(time.Now().UnixNano())
}
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func RandStringRunes(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
func main() {
db, err := sql.Open("postgres", "postgresql://root@localhost:26257/test?sslmode=disable")
if err != nil {
panic(err)
}
sqlStr := "INSERT INTO customers(first_name, last_name, age) VALUES"
insert := ""
for i := 0; i < 1000000; i++ {
fname := RandStringRunes(30)
lname := RandStringRunes(39)
age := rand.Intn(100)
insert += fmt.Sprintf("('%s', '%s', %d),", fname, lname, age)
if i%5000 == 0 {
sql := sqlStr + strings.Trim(insert, ",")
insert = ""
_, err := db.Exec(sql)
if err != nil {
panic(err)
}
}
}
if len(insert) > 0 {
sql := sqlStr + strings.Trim(insert, ",")
insert = ""
_, err := db.Exec(sql)
if err != nil {
panic(err)
}
}
}
结果:
MariaDB的:
[root@mariadb ~]# time ./insert
real 0m40.650s
user 0m33.784s
sys 0m0.112s
[root@mariadb ~]#
CockroachDB:
[root@cockroachdb ~]# time ./insert
real 3m42.909s
user 0m35.620s
sys 0m0.144s
我正在使用MariaDB:
[root@mariadb ~]# mysql --version
mysql Ver 15.1 Distrib 5.5.52-MariaDB, for Linux (x86_64) using readline 5.1
和CockroachDB:
[root@cockroachdb ~]# cockroach version
Build Tag: v1.0.1
Build Time: 2017/05/25 15:17:49
Distribution: CCL
Platform: linux amd64
Go Version: go1.8.1
C Compiler: gcc 6.3.0
Build SHA-1: 50fd18dcf8da75a0f4980344a885fe6105d0cf23
Build Type: release
[root@cockroachdb ~]#
我知道使用随机数据可能会影响数字,但我仍然几乎所有时间都得到这些数字,因此有足够的一致性。
这些数字对于CockroachDB是否正确,上述版本的插入速度是否较慢?
此外,计算表中的所有记录也很慢(select count(*) from customers
),因为我从MariaDB服务器得到的结果集中没有得到计时器,所以不确定多少,但是MariaDB服务器在5秒内返回结果,而CockroachDB在计数时间超过10秒。
我喜欢改变表格以添加新列,例如使用CockroachDB即时,而MariDB在具有5M记录的表格上花了将近30秒。
任何想法都受到高度赞赏 感谢。
答案 0 :(得分:7)
CockroachDB 1.0.1(和1.0)剩下debug assertion,导致批量操作大幅减速。该断言将在1.0.2中删除(计划在几周内发布)。为了比较,这是我在1.0.1运行时看到的:
$ time ./insert
real 2m3.125s
user 0m35.942s
sys 0m6.659s
这是(未发布的)1.0.2:
$ time ./insert
real 0m48.145s
user 0m36.638s
sys 0m6.692s
尽管有所改善,但我预计性能仍将低于MariaDB。部分原因是CockroachDB的架构。即使在运行单个节点时,它也会经历许多分布式执行所需的代码路径。部分原因是成熟。 MariaDB已经过多年优化,而我们只处于CockroachDB工作的早期阶段。