У меня есть этот простой запрос
SELECT item_code, stock_value, name, warehouse
FROM `tabStock Ledger Entry` sle
WHERE posting_date <= '2020-08-01'
AND warehouse = 'bom'
ORDER BY timestamp(posting_date, posting_time) DESC,
Creation DESC
Это занимает почти 3 секунды для 1000 записей ... без предложения Order By требуется менее 1 se c для запроса всей таблицы. в самой таблице в настоящее время содержится более 1 млн записей.
show processlist
всегда застревает в состоянии создания индекса сортировки.
Запрос объяснения показал:
+------+-------------+-------+------+------------------------------+-----------+---------+-------+--------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+------------------------------+-----------+---------+-------+--------+----------------------------------------------------+
| 1 | SIMPLE | sle | ref | posting_sort_index,warehouse | warehouse | 563 | const | 127740 | Using index condition; Using where; Using filesort |
+------+-------------+-------+------+------------------------------+-----------+---------+-------+--------+----------------------------------------------------+
индексы таблицы следующим образом:
+-----------------------+------------+-------------------------------+--------------+--------------+--
| Table | Non_unique | Key_name | Seq_in_index | Column_name | C
+-----------------------+------------+-------------------------------+--------------+--------------+--
| tabStock Ledger Entry | 0 | PRIMARY | 1 | name | A
| tabStock Ledger Entry | 1 | item_code | 1 | item_code | A
| tabStock Ledger Entry | 1 | parent | 1 | parent | A
| tabStock Ledger Entry | 1 | posting_sort_index | 1 | posting_date | A
| tabStock Ledger Entry | 1 | posting_sort_index | 2 | posting_time | A
| tabStock Ledger Entry | 1 | posting_sort_index | 3 | name | A
| tabStock Ledger Entry | 1 | voucher_no_voucher_type_index | 1 | voucher_no | A
| tabStock Ledger Entry | 1 | voucher_no_voucher_type_index | 2 | voucher_type | A
| tabStock Ledger Entry | 1 | warehouse | 1 | warehouse | A
| tabStock Ledger Entry | 1 | warehouse | 2 | posting_date | A
+-----------------------+------------+-------------------------------+--------------+--------------+--
Добавлен индекс для (дата_поста, склад) или (склад, дата_поста), но это не помогает .. похоже, что запрос всегда использует сортировку файлов
innodb_buffer_pool_size
- 2Гб. .из 4G RAM. Я думаю, этого достаточно ... это не мега гигантская база данных
SHow Create table
следующим образом:
+-----------------------+---------------------------------------------------------------
| Table | Create Table
+-----------------------+---------------------------------------------------------------
| tabStock Ledger Entry | CREATE TABLE `tabStock Ledger Entry` (
`name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`creation` datetime(6) DEFAULT NULL,
`modified` datetime(6) DEFAULT NULL,
`modified_by` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`owner` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`docstatus` int(1) NOT NULL DEFAULT 0,
`parent` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`parentfield` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`parenttype` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`idx` int(8) DEFAULT NULL,
`actual_qty` decimal(18,6) NOT NULL DEFAULT 0.000000,
`warehouse` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`qty_after_transaction` decimal(18,6) NOT NULL DEFAULT 0.000000,
`fiscal_year` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`company` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`serial_no` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`incoming_rate` decimal(18,6) NOT NULL DEFAULT 0.000000,
`stock_queue` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`item_code` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`voucher_detail_no` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`project` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`stock_value_difference` decimal(18,6) NOT NULL DEFAULT 0.000000,
`stock_uom` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`voucher_type` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`batch_no` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`valuation_rate` decimal(18,6) NOT NULL DEFAULT 0.000000,
`posting_date` date DEFAULT NULL,
`voucher_no` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`stock_value` decimal(18,6) NOT NULL DEFAULT 0.000000,
`is_cancelled` varchar(140) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`posting_time` time(6) DEFAULT NULL,
`outgoing_rate` decimal(18,6) NOT NULL DEFAULT 0.000000,
`_comments` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`_liked_by` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`_assign` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`_user_tags` text COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`to_rename` int(1) NOT NULL DEFAULT 1,
PRIMARY KEY (`name`),
KEY `item_code` (`item_code`),
KEY `parent` (`parent`),
KEY `posting_sort_index` (`posting_date`,`posting_time`,`name`),
KEY `voucher_no_voucher_type_index` (`voucher_no`,`voucher_type`),
KEY `warehouse` (`warehouse`,`posting_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPRESSED
+-----------------------+---------------------------------------------------------------
БОЛЬШЕ
Я удалил функцию отметки времени и закажите только posting_date .. запустите запрос из консоли mariadb .. наконец, потребовалось всего <2 se c, чтобы загрузить более 200 000 результирующих строк. </p>
Но mariadb-slow.log показал мне по-другому, если бы я запустил тот же запрос из веб-приложения .. он взял> 4se c для того же результата. Что может вызвать это?
# User@Host: _5839b22099d630d5[_5839b22099d630d5] @ localhost [127.0.0.1]
# Thread_id: 685 Schema: _5839b22099d630d5 QC_hit: No
# Query_time: 4.101652 Lock_time: 0.000055 Rows_sent: 226657 Rows_examined: 226657
# Rows_affected: 0
SET timestamp=1596384652;
SELECT item_code, stock_value, name, warehouse
FROM `tabStock Ledger Entry` sle
WHERE posting_date <= '2020-08-02' AND warehouse = 'bom'
ORDER BY posting_date DESC;
ОБЪЯСНЕНИЕ В JSON
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "sle",
"access_type": "range",
"possible_keys": [
"warehouse",
"posting_date",
"posting_sort_index",
"warehouse_2"
],
"key": "warehouse_2",
"key_length": "567",
"used_key_parts": ["warehouse", "posting_date"],
"rows": 126605,
"filtered": 100,
"attached_condition": "sle.warehouse <=> 'bom' and sle.posting_date <= '2020-08-02' and sle.warehouse = 'bom'"
}
}