比MySQL更快的数据库,关于数据库:在这种情况下,MyISAM比mysql中的InnoDB快得多...

我一直在编写计算结果,该算法计算InnoDB表中客户之间的距离。例如,如果我的客户是A,B,C和D,则数据库中的表格如下所示:

From | To    | Distance

A     B        344

A     C        274

A     D        182

B     C        338

等等...我认为我将达到5000万,这是很多行。

其他列是product_type和value。那些告诉我客户B(列中的customer_to)买了多少product_type。这意味着我每次都有多次,具体取决于客户B购买的product_types数量。

我需要查询将每个客户与他的邻居购买的产品和价值分组。查询如下所示:

select customer_from, product_type, avg(value) as opportunity

from customer_distances

where distance < 500

group by customer_from, product_type

order by opportunity desc;

innodb表无法回答我那个查询。尽管我将net_read_timeout更改为28800,但在查询期间mysql连接丢失了。

我认为它与用于事务处理的innodb构建有关,而不是用于密集查询。所以我用MyIsam作为引擎创建了一个新表,并插入 - 从innodb表中选择所有记录。

正如预期的那样,选择速度非常快(70 segs),所有其他选择都像count(distinct customer_from),几乎是瞬间的。

出于好奇,我试图继续在myisam表中插入距离的过程。当程序开始运行至少比在innodb表上工作时快100倍时,我感到很惊讶 - 对于INSERTS!

对于每个客户,程序会插入3000行(每个product_type每个邻居一个。每个客户有300个邻居和10个product_types)。使用innodb表插入一个客户需要40到60秒(aprox.3000行)。使用myisam表,插入3个客户(9000行aprox)需要1秒钟。

一些额外的信息:

mysql数据库在我的PC(localhost)中。

用java编写的程序是从我的电脑上运行的。

我正在使用预处理语句,我只更改每个语句之间的数据

行和下一个。这与这个问题有关

为什么myisam存储引擎比Innodb存储引擎更快

所以总的来说问题是:

为什么MyISAM快速插入语句?

你怎么看?

编辑1:我正在为两个表添加创建语句,即innodb和myisam。

编辑2:我删除了一些无用的信息,并在这里和那里形成了一点点。

/* INNODB TABLE */

CREATE TABLE `customer_distances` (

`customer_from` varchar(50) NOT NULL,

`customer_from_type` varchar(50) DEFAULT NULL,

`customer_from_segment` varchar(50) DEFAULT NULL,

`customer_from_district` int(11) DEFAULT NULL,

`customer_from_zone` int(11) DEFAULT NULL,

`customer_from_longitud` decimal(15,6) DEFAULT NULL,

`customer_from_latitud` decimal(15,6) DEFAULT NULL,

`customer_to` varchar(50) NOT NULL,

`customer_to_type` varchar(50) DEFAULT NULL,

`customer_to_segment` varchar(50) DEFAULT NULL,

`customer_to_district` int(11) DEFAULT NULL,

`customer_to_zone` int(11) DEFAULT NULL,

`customer_to_longitud` decimal(15,6) DEFAULT NULL,

`customer_to_latitud` decimal(15,6) DEFAULT NULL,

`distance` decimal(10,2) DEFAULT NULL,

`product_business_line` varchar(50) DEFAULT NULL,

`product_type` varchar(50) NOT NULL,

`customer_from_liters` decimal(10,2) DEFAULT NULL,

`customer_from_dollars` decimal(10,2) DEFAULT NULL,

`customer_from_units` decimal(10,2) DEFAULT NULL,

`customer_to_liters` decimal(10,2) DEFAULT NULL,

`customer_to_dollars` decimal(10,2) DEFAULT NULL,

`customer_to_units` decimal(10,2) DEFAULT NULL,

`liters_opportunity` decimal(10,2) DEFAULT NULL,

`dollars_opportunity` decimal(10,2) DEFAULT NULL,

`units_oportunity` decimal(10,2) DEFAULT NULL,

PRIMARY KEY (`cliente_desde`,`cliente_hasta`,`grupo`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/* MYISAM TABLE */

CREATE TABLE `customer_distances` (

`customer_from` varchar(50) NOT NULL,

`customer_from_type` varchar(50) DEFAULT NULL,

`customer_from_segment` varchar(50) DEFAULT NULL,

`customer_from_district` int(11) DEFAULT NULL,

`customer_from_zone` int(11) DEFAULT NULL,

`customer_from_longitud` decimal(15,6) DEFAULT NULL,

`customer_from_latitud` decimal(15,6) DEFAULT NULL,

`customer_to` varchar(50) NOT NULL,

`customer_to_type` varchar(50) DEFAULT NULL,

`customer_to_segment` varchar(50) DEFAULT NULL,

`customer_to_district` int(11) DEFAULT NULL,

`customer_to_zone` int(11) DEFAULT NULL,

`customer_to_longitud` decimal(15,6) DEFAULT NULL,

`customer_to_latitud` decimal(15,6) DEFAULT NULL,

`distance` decimal(10,2) DEFAULT NULL,

`product_business_line` varchar(50) DEFAULT NULL,

`product_type` varchar(50) NOT NULL,

`customer_from_liters` decimal(10,2) DEFAULT NULL,

`customer_from_dollars` decimal(10,2) DEFAULT NULL,

`customer_from_units` decimal(10,2) DEFAULT NULL,

`customer_to_liters` decimal(10,2) DEFAULT NULL,

`customer_to_dollars` decimal(10,2) DEFAULT NULL,

`customer_to_units` decimal(10,2) DEFAULT NULL,

`liters_opportunity` decimal(10,2) DEFAULT NULL,

`dollars_opportunity` decimal(10,2) DEFAULT NULL,

`units_oportunity` decimal(10,2) DEFAULT NULL,

PRIMARY KEY (`cliente_desde`,`cliente_hasta`,`grupo`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8;

这些表是否相同(索引等)?并且可能会影响性能的引擎有单独的服务器设置(例如内存缓存大小)。

您应该规范化产品销售数据。该表没有像目前设计的那样有意义。

相同的表,相同的服务器。

我需要这样的数据用于报告目的。我需要它更快,如果我规范化数据,那么数据库需要连接才能构建结果。

有关性能的问题通常需要为所有相关表创建一个CREATE,以及一个EXPLAIN

你不会说服我这样对这些数据进行非规范化,并使用5000万行的表的大小加倍或三倍,这真的会使你的报告运行得更快。同样可能他们会跑得慢。你打算怎么维护这些数据?

在事务数据库中,信息被规范化,并且数据随着业务的运行而变化。此表是专门为该报告创建的。这是一张带有地图的画面,您可以按照产品类型查看彼此接近的客户及其交易。查询将类似于select * from customer_distances where customer_from = '238483'。我可能错了,我不确定,但我认为数据库更快地返回所有具有条件的寄存器,而不是加入距离和销售的客户。

我将为两个表草莓添加创建句子。我不知道EXPLAIN是什么。

"相同的服务器"并不重要......好吧,但它不是我所说的。 MySQL在单个服务器实例上为两个引擎分别设置(如第二个答案中所述)。

你是对的我不明白你的评论。应该确定引擎之间的不同设置。我有一段时间没有参与该项目,但只要我得到答案,我就会在这里公布结果。

插入

默认情况下,InnoDB会立即"提交"每个INSERT。这可以通过一次聚集100-1000行来解决。

批量插入将加速MyISAM和InnoDB - 可能是10倍。

了解autocommit和BEGIN..COMMIT。

选择

InnoDB比MyISAM消耗更多的磁盘空间 - 通常为2x-3x;这可能影响表扫描

对于该查询,(customer_from,product_type,distance)上的复合索引可能对两个引擎都有帮助。

调音

仅运行MyISAM时,将key_buffer_size设置为20%的RAM和innodb_buffer_pool_size=0。

仅运行InnoDB时,将key_buffer_size设置为仅10M且innodb_buffer_pool_size设置为70%的RAM。

规范化,节省空间

更小 - >更多可缓存 - >更少I / O - >更快(在任一引擎中)

在大多数情况下,DECIMAL(10,2)不是最好的。考虑FLOAT用于非货币(例如distance)。考虑更少的数字;最多可处理99,999,999.99,占用5个字节。

拥有复制列通常不是一个好主意,例如customer_from和customer_to的10列。有一个Customers表,其中包含两个表。

您的每个纬度和纵向都是7个字节,并且具有不必要的分辨率。建议latidud DECIMAL(6,4)和longitud (7,4),总共7个字节。 (这些分辨率为16米/ 52英尺。)

结果

在这些建议之后,50M行表将非常小,并且在两个引擎中运行得非常快。然后再次运行比较。

非常感谢你的回答。 我将进行更改并在此处记录结果。

@DagoBorda - 还有结果吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值