我使用数百万条用于搜索结果的记录对表进行索引。我通过ASC或DESC订单显示结果。我的问题是列应该有索引吗?我在那张桌子上还有2个索引。如何通过为该列创建索引来影响性能?
答案 0 :(得分:10)
按列排序用于排序结果集,而不是过滤。 order by子句中提到的列的索引不太可能改变任何内容,特别是如果它不用于过滤数据。
答案 1 :(得分:3)
实际上 - 对于数百万行更好地应用一些经过深思熟虑的索引,开始担心空间性能问题并不是那么大的数据集。
<强>但强>
如果您每天阅读一次该表并每秒更新/删除行100次 - 那么索引的效果可能会降低主要操作的性能,而偶尔选择会更好。
所以,答案一如既往 - 取决于
答案 2 :(得分:1)
这取决于您的查询。 MySQL可以对where子句和order by都使用复合索引。如果您显式地包含一个包含相同列列表的ORDER BY子句,则MySQL会对其进行优化,而不会造成任何速度损失,尽管排序仍然会发生。如果查询包含GROUP BY,但您希望避免对结果进行排序的开销,则可以通过指定ORDER BY NULL来抑制排序。
更多详细信息
http://download.nust.na/pub6/mysql/doc/refman/5.1/en/order-by-optimization.html
如果您不擅长MySQL优化,则可以使用SmartMySQL等一些好的工具,这些工具可以根据表结构及其数据为查询确定最佳索引。它是免费的GUI工具,与MySQL的Workbench相比,它可以优化查询并加快您的开发速度10倍。
下载它答案 3 :(得分:0)
在索引列上使用ORDER BY不是一个好主意。实际上,使用索引的目的是使搜索更快,因此索引列有助于按排序顺序维护数据。我建议你在非索引列使用ORDER BY。我在MySql上运行了一个示例查询,并得到如下所述的结果。
SELECT
ci.id AS item_id, ci.brand_id, ci.category_id,
ci.item_size_type, ci.is_express_processing, ci.packing,
ci.parent_service_id, ci.product_id, ci.size,
ci.create_date AS item_create_date, cis.service_id, cis.quantity
FROM
cart AS c
INNER JOIN
cart_items AS ci ON ci.cart_id = c.id
LEFT JOIN
cart_item_services AS cis ON cis.item_id = ci.id
WHERE
c.id = 144
ORDER BY
c.create_date;
我在非索引列ORDER BY
上使用create_date
,结果如下:
# Time: 2017-11-03T10:30:33.237056Z
# User@Host: root[root] @ localhost [] Id: 3
# Query_time: 0.000340
# Lock_time: 0.000154 Rows_sent: 2 Rows_examined: 4
现在我将在索引列ORDER BY
上使用item_id
:
SELECT
ci.id AS item_id, ci.brand_id, ci.category_id,
ci.item_size_type, ci.is_express_processing, ci.packing,
ci.parent_service_id, ci.product_id, ci.size,
ci.create_date AS item_create_date, cis.service_id, cis.quantity
FROM
cart AS c
INNER JOIN
cart_items AS ci ON ci.cart_id = c.id
LEFT JOIN
cart_item_services AS cis ON cis.item_id = ci.id
WHERE
c.id = 144
ORDER BY
item_id;
现在我得到的结果如下。
# Time: 2017-11-03T10:30:47.802392Z
# User@Host: root[root] @ localhost [] Id: 3
# Query_time: 0.000383
# Lock_time: 0.000176 Rows_sent: 2 Rows_examined: 4
因此,在上面的结果中,我们可以看到索引列Query_time和Lock_time高于非索引列。
有关查询标准和性能的更详细分析,请参阅以下链接: