Gần đây tôi đã chuyển các bảng dự án của tôi sang InnoDB (nghĩ rằng các mối quan hệ sẽ là một điều tốt đẹp để có). Tôi đang sử dụng một tập lệnh PHP để lập chỉ mục khoảng 500 sản phẩm cùng một lúc.InnoDB chèn rất chậm và chậm lại
Một từ/id gắn bảng lưu trữ:
CREATE TABLE `windex` (
`word` varchar(64) NOT NULL,
`wid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`count` int(11) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`wid`),
UNIQUE KEY `word` (`word`)
) ENGINE=InnoDB AUTO_INCREMENT=324551 DEFAULT CHARSET=latin1
Một bảng các cửa hàng sản phẩm id/từ hiệp hội id:
CREATE TABLE `indx_0` (
`wid` int(7) unsigned NOT NULL,
`pid` int(7) unsigned NOT NULL,
UNIQUE KEY `wid` (`wid`,`pid`),
KEY `pid` (`pid`),
CONSTRAINT `indx_0_ibfk_1` FOREIGN KEY (`wid`) REFERENCES `windex` (`wid`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `indx_0_ibfk_2` FOREIGN KEY (`pid`) REFERENCES `product` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Các kịch bản đã được thử nghiệm sử dụng MyISAM và nó chỉ số sản phẩm tương đối nhanh (nhiều , nhanh hơn nhiều so với InnoDB). Lần đầu tiên chạy trong InnoDB nó đã được ridiculously chậm nhưng sau khi làm tổ nhiều giá trị với nhau tôi đã kết thúc tăng tốc nó lên bởi rất nhiều (nhưng không đủ).
Tôi cho rằng innodb sẽ nhanh hơn nhiều đối với loại điều này vì khóa rowlevel nhưng đó không phải là trường hợp.
tôi xây dựng một truy vấn mà trông giống như sau:
SELECT
title,keywords,upc,...
FROM product
WHERE indexed = 0
LIMIT 500
tôi tạo ra một vòng lặp và điền một mảng với tất cả những từ mà cần phải được bổ sung vào Windex và tất cả các cặp từ id/sản phẩm id cần được thêm vào indx_0.
Bởi vì innodb tiếp tục tăng giá trị tăng tự động của tôi bất cứ khi nào tôi thực hiện "REPLACE INTO" hoặc "INSERT IGNORE INTO" không thành công do giá trị trùng lặp, tôi cần đảm bảo giá trị tôi thêm chưa tồn tại. Để làm điều đó đầu tiên tôi chọn tất cả các giá trị mà tồn tại sử dụng một truy vấn như ví dụ:
SELECT wid,word
FROM windex
WHERE
word = "someword1" or word = "someword2" or word = "someword3" ... ...
Sau đó, tôi lọc ra các mảng của tôi chống lại những kết quả mà tồn tại vì vậy tất cả các từ mới tôi thêm là 100% mới.
Điều này mất khoảng 20% thời gian thực hiện tổng thể. 80% còn lại đi vào việc thêm các giá trị của cặp vào indx_0, trong đó có nhiều giá trị hơn.
Dưới đây là ví dụ về những gì tôi nhận được.
0.4806 giây để chọn sản phẩm. (Tổng số 0,4807 giây).
0,0319 giây để thu thập 500 mục. (Tổng số 0,5126 giây).
5.2396 giây để chọn giá trị windex để so sánh. (5.7836 giây).
1.8986 giây để cập nhật số lượng. (Tổng cộng 7.6822 giây).
0,0641 giây để thêm 832 bản ghi windex. (Tổng số 7,7464 giây).
17,2725 giây để thêm chỉ mục của 3435 cặp pid/wid. (Tổng số 25.7752 giây).
Hoạt động mất 26,07 giây để lập chỉ mục 500 sản phẩm.
Các cặp 3435 đang được tất cả được thực hiện trong một truy vấn như:
INSERT INTO indx_0(pid,wid)
VALUES (1,4),(3,9),(9,2)... ... ...
Tại sao là InnoDB nên chậm hơn nhiều so với MyISAM trong trường hợp của tôi?
Ý tưởng chỉ mục từ để tạo một số chức năng tìm kiếm? Nếu đó là trường hợp, đã được thực hiện điều đó, hãy kiểm tra một công cụ tìm kiếm thực sự như solr hoặc mysql tìm kiếm fulltext ví dụ. Không thể làm tốt hơn các tác vụ cụ thể đó. –