我一直在寫一個計算InnoDB表中客戶之間距離的算法的結果。例如,如果我的客戶分別爲A,B,C和d,在數據庫中的表看起來像這樣,其他列中:在這種情況下,MyISAM比mysql中的InnoDB快得多
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購買多少個產品類型。
我需要查詢來將每個客戶與他的鄰居購買的產品和價值進行分組。查詢如下所示:
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個分類),而其他所有選擇都像count(不同的customer_from),其中幾乎是瞬時的。
只是爲了好奇,我試圖繼續在myisam表中插入距離的過程。對於我來說,當程序開始運行至少比在innodb表上工作快100倍時,對我來說是一個驚喜!
對於每個客戶,程序會插入類似3000行的東西(每個product_type的每個鄰居一個,例如300個鄰居和每個客戶的10個product_types)。用innodb表插入一個客戶需要40到60秒(約3000行)。使用myisam表格,插入3個客戶需要1秒鐘(9000行aprox)。
一些額外的信息:
- MySQL數據庫是在我的電腦(本地主機)。
- 用java編寫的程序,正在從我的電腦上運行。
- 我正在使用準備好的語句,並且我只更改每個 行和下一行之間的數據。這是有關這個問題 Why is myisam storage engine is faster than Innodb storage engine
因此,在總結的問題是: 爲什麼是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;
這些表格是否相同(索引等)?並且對於可能影響性能的引擎,有單獨的服務器設置(如內存緩存大小)。 – Uueerdo
您應該規範產品銷售數據。桌子沒有現在設計的意義。 – EJP
相同的表,相同的服務器。 –