如何确定集合在 MySQL 中没有 SELECT 迭代的表中可用?

Posted

技术标签:

【中文标题】如何确定集合在 MySQL 中没有 SELECT 迭代的表中可用?【英文标题】:How to determine the collection is available in a table without SELECT iteration in MySQL? 【发布时间】:2016-05-12 03:53:11 【问题描述】:

带有 WHERE 子句的 SELECT 通过迭代返回与谓词匹配的新项目序列。

有什么方法可以预测给定的搜索条件在 mysql 中是否可用(布尔值)?

示例 SQL

CREATE TABLE Ledger
(
PersonID int,
ldate date,    
dr float,
cr float,
bal float
);

INSERT INTO Ledger(PersonID, ldate, dr, cr, bal)
VALUES 
('1001', '2016-01-23', 105 ,0 ,0),
('1001', '2016-01-24', 0, 5.25, 0),
('1002', '2016-01-24', 0, 150, 0),
('1001', '2016-01-25', 0, 15, 0),
('1002', '2016-01-25', 73, 0, 0); 

这里我需要检查 PersonID 1002 是否存在

常见的检查方式是

SELECT COUNT(PersonID) > 0 AS my_bool FROM Ledger WHERE PersonID = 1002

SELECT COUNT(*) > 0 AS my_bool FROM Ledger WHERE ldate = '2016-01-24' AND (bal > 75 AND bal <100)

以上两个查询仅供参考。

但是,上面的 SELECT 查询会迭代整个集合并过滤结果。它会降低非常大的数据库集合(超过 30 万条活动记录)的性能。

是否有一个带有谓词的版本(在这种情况下它返回是否有任何项目匹配)和一个没有谓词的版本(在这种情况下它返回查询到目前为止是否包含任何项目)。

这里我给出了一个非常简单的 WHERE 子句。但在实际场景中有 复杂的 WHERE 子句。 .NET 有一个方法 .Any() 它预测 集合而不是 .Where()。

如何以有效的方式实现这一目标?

【问题讨论】:

在 PersonID 上创建索引以最小化扫描行数。 @SubrataDeyPappu - 上面的 SQL 是一个示例,但在主数据库中,列是索引列。这里我给出了一个非常简单的 WHERE 子句。但在实际场景中,存在复杂的 WHERE 子句。请帮助我.. 那么请分享您的复杂查询。 如果您的数据过多,您还可以考虑将特定范围的记录存储到分区中的数据分区,这样搜索时只会扫描有限的数据。 @SubrataDeyPappu 我更新了查询。请检查一次。 【参考方案1】:

您可以使用EXISTS进行优化

SELECT EXISTS
(
  SELECT 1
  FROM Ledger 
  WHERE ldate = '2016-01-24' 
  AND (bal > 75 AND bal < 100)
) AS my_bool

一旦找到匹配项,它将立即返回。

Click here to have a play on SQL Fiddle

更多信息在这里:

Optimizing Subqueries with EXISTS Strategy

Best way to test if a row exists in a MySQL table

Subqueries with EXISTS vs IN - MySQL

【讨论】:

以上是关于如何确定集合在 MySQL 中没有 SELECT 迭代的表中可用?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL的权限都有哪些

mysql应用

MySQL性能优化之道

redis做mysql的缓存

如何在laravel中将集合变成数组

如何在mysql的列中找到缺少的月份?