[英]In this case MyISAM is dramatically faster than InnoDB in mysql
我一直在編寫計算結果,該算法計算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秒鍾。
一些額外的信息:
總而言之,問題是:為什么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;
插入
INSERT
。 這可以通過一次聚集100-1000行來解決。 autocommit
和BEGIN..COMMIT
。 選擇
調音
key_buffer_size
的RAM和20% innodb_buffer_pool_size=0
。 key_buffer_size
只有10M和innodb_buffer_pool_size
的RAM 70%。 規范化,節省空間
DECIMAL(10,2)
並不是最好的。 考慮FLOAT
用於非貨幣(例如distance
)。 考慮更少的數字; 最多可處理99,999,999.99,占用5個字節。 customer_from
和customer_to
的10列。 有一個Customers
表,其中包含兩者。 latidud DECIMAL(6,4)
和longitud (7,4)
, 總共 7個字節。 (這些分辨率為16米/ 52英尺。) 結果
在這些建議之后,50M行表將非常小,並且在兩個引擎中運行得非常快。 然后再次運行比較。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.