【问题标题】:How to add a LIMIT to a user-generated sql query如何向用户生成的 sql 查询添加 LIMIT
【发布时间】:2019-01-03 22:57:56
【问题描述】:

我已经构建了一个查询编辑器,用户可以在其中输入查询。但是,它需要将用户的输入限制为 1000 个结果,否则用户可能会输入类似的内容:

SELECT * FROM mybigtable

它可以尝试下载 10 亿个结果。

实施限制的最佳方式是什么?我想到的第一种方法是:

SELECT * FROM (
    user-query
) x LIMIT 1000

但是,这会在执行实际限制之前执行整个查询(并且可能需要很长时间)。对用户的 sql 输入实施严格限制的最佳方法是什么?

【问题讨论】:

  • 我希望查询优化器将其重写为user-query LIMIT MIN(user-limit, 1000)...
  • @Nick 当我在 mysql 中尝试一个大表时它不会:select * from (select * from main_item) x limit 100
  • 你的方法是正确的。您的查询仅选择 1000 行。就这些
  • @Simonare 我从理论上理解这是正确的,但我不希望最终用户在发出查询时等待 20 分钟以返回 1000 个结果,如果它正在下载子选择语句中的整个表。
  • 它不下载。 DBMS 系统以这种方式是智能的 :)

标签: mysql sql


【解决方案1】:

评论太长了。

我认为没有通用的解决方案。

将用户查询包装在 SELECT * FROM ... LIMIT 1000 语句中很有吸引力,但是 ;

  • 存在可能产生无效 SQL 的极端情况,例如,如果用户查询包含 CTE(WITH 子句必须放在查询的最开头)
  • 虽然它会愉快地限制返回给用户的行数,但不会阻止数据库扫描整个结果集

第二种用例的典型解决方案是根据自动递增的整数列(通常是表的主键)过滤行。但这更难通用。

简而言之:远距离操作 SQL 是很棘手的:如果您想为您的用例提供完整的解决方案,请让自己成为一个真正的查询构建器(或至少一个 sql 解析器)。

【讨论】:

  • 谢谢。这可以使用sqlparse 之类的东西来完成吗?如果是这样,你想展示一个如何做到这一点的例子,我会接受你的回答吗?
  • @DavidL ... 是的,如果您使用 python,sqlparse 是一个不错的选择。这超出了您原始帖子的范围,但有很多资源可供学习,例如this recent SO post
  • 当然,我会再问一个更具体的问题。
  • 您是否可以建议任何允许操作查询的 sql 解析器?看起来 sqlparse 是只读的。
猜你喜欢
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 2022-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-29
  • 2021-08-30
相关资源
最近更新 更多