Tôi đang cố gắng sử dụng ZF2 Paginator trên một số bộ hồ sơ lớn (khoảng 10 triệu trong trường hợp xấu nhất với bộ lọc tìm kiếm). Bảng của tôi ở định dạng InnoDB, mà tôi hiểu không giữ một số lượng nhất định như một phần của siêu dữ liệu.Hiệu suất thất thoát cho Count() sử dụng ZF2 Paginator trên InnoDB Tables
Tôi nhận thấy rằng tôi có thể mở rộng lớp Zend \ Paginator \ Adapter \ DbSelect và thực hiện phương thức count() của riêng tôi sử dụng dữ liệu đếm mà tôi lưu trữ theo cách thủ công trong bảng khác, nhưng tôi không chắc chắn về cách lưu trữ số lượng tất cả các hoán vị có thể có của các tìm kiếm có thể được thực hiện.
Giá trị mặc định ZF2 DbSelect adapter sử dụng phương pháp này:
<?php
public function count()
{
if ($this->rowCount !== null) {
return $this->rowCount;
}
$select = clone $this->select;
$select->reset(Select::LIMIT);
$select->reset(Select::OFFSET);
$select->reset(Select::ORDER);
$countSelect = new Select;
$countSelect->columns(array('c' => new Expression('COUNT(1)')));
$countSelect->from(array('original_select' => $select));
$statement = $this->sql->prepareStatementForSqlObject($countSelect);
$result = $statement->execute();
$row = $result->current();
$this->rowCount = $row['c'];
return $this->rowCount;
}
?>
Đây là một câu hỏi ví dụ rất đơn giản mà phương pháp sản xuất cho tôi:
SELECT
COUNT(1) AS `c`
FROM
(
SELECT
`contacts`.`id` AS `id`,
`contacts`.`firstname` AS `firstname`,
`contacts`.`middlename` AS `middlename`,
`contacts`.`lastname` AS `lastname`,
`contacts`.`gender` AS `gender`
FROM
`contacts`
WHERE
`contacts`.`trash` = '0'
) AS `original_select`
Tôi không chắc chắn những gì hiệu suất sẽ là trên MyISAM bảng, nhưng điều này không cho tôi do nó ăn tất cả các không gian có thể giải phóng trên Amazon RDS (25GB, db.m1.small) trường hợp mà nó đang chạy. Như một so sánh, chỉ chạy truy vấn bên trong (bản gốc), nó hoàn thành trong 100 giây (chắc chắn là không tốt) và trả về 7.39 triệu bản ghi.
Dưới đây là giải thích từ truy vấn bên trong (một giải thích về số lượng người ta cũng chết vì không gian đĩa trên máy chủ RDS):
+----+-------------+----------+------+---------------+-------+---------+-------+---------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+----------+------+---------------+-------+---------+-------+---------+-------+ | 1 | SIMPLE | contacts | ref | trash | trash | 1 | const | 3441317 | | +----+-------------+----------+------+---------------+-------+---------+-------+---------+-------+ 1 rows in set (0.04 sec)
Có bất cứ điều gì có thể được thực hiện để điều chỉnh này tốt hơn? Có phải cách mà ZF2 Paginator xử lý đếm không tương thích theo cách nào đó với cách mà InnoDB làm việc không? Làm thế nào những người khác sẽ xử lý bộ nhớ đệm của tất cả các truy vấn có thể nếu chúng tôi cho phép tìm kiếm trên hầu hết các trường trong cơ sở dữ liệu?
Cảm ơn trước ...
Vấn đề này là cố hữu đối với InnoDB, MyISAM không có vấn đề này vì nó theo dõi số lượng hàng trong bảng trong siêu dữ liệu của nó. Nó có lẽ là tốt nhất để chỉ cần tinh chỉnh các truy vấn trong một giao diện người dùng cơ sở dữ liệu và xem những gì có hiệu lực nó. Thay vì COUNT (1) bạn có thể thử COUNT (id) ví dụ hoặc cho MySQL sử dụng một chỉ mục cụ thể bằng cách sử dụng mysql> count count (1) từ ... sử dụng chỉ mục (your_index) – Ruben
** COUNT (1) **: 15 phút 36 giây; ** COUNT (id) **: 18 phút 8.83 giây – jcq