首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >数值范围优化

数值范围优化
EN

Stack Overflow用户
提问于 2011-04-06 14:03:28
回答 4查看 274关注 0票数 3

我有一个设定的数值范围,我想优化。

下面是一个简单的初始值示例:

代码语言:javascript
运行
复制
Start    End
9        12
1        2
60       88
10       11
79       80

我期望优化后的输出:

代码语言:javascript
运行
复制
Start    End
1        2
9        12
60       88

这些是存储在left数据库中的修改前顺序树遍历(嵌套集)数据中的MySQL和right值。我使用它们从结果中排除不活动的分支,并且目前根本没有优化范围。我想我可能会从优化使用前的范围中获得性能上的提高。

更多信息

使用NOT BETWEEN子句将这些值传递到查询中,以排除树中的非活动分支。我认为可以通过使用最小范围集来优化该查询的性能。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-04-07 08:05:29

下面是一个SQL,它将返回您想要的

代码语言:javascript
运行
复制
mysql> CREATE TABLE sample (Start INT, End INT);

mysql> INSERT sample VALUES (9,12),(1,2),(60,88),(10,11),(79,80);

mysql> SELECT * 
    -> FROM sample s 
    -> WHERE NOT EXISTS (SELECT 1 
    ->                   FROM sample 
    ->                   WHERE s.Start > Start AND s.Start < End);
+-------+------+
| Start | End  |
+-------+------+
|     9 |   12 |
|     1 |    2 |
|    60 |   88 |
+-------+------+

当然,您可以使用上面的SQL创建视图、将数据移动到另一个表或删除行。

注意:我不太清楚你为什么要做这个‘优化’。

编辑:

查询可以重写为

代码语言:javascript
运行
复制
SELECT s.* 
FROM sample s LEFT JOIN 
     sample s2 ON s.Start > s2.Start AND s.Start < s2.End 
WHERE s2.start IS NULL;

这将创建不同的执行计划(2xSimpleSelectvs主/依赖子查询的存在),因此性能可能有所不同。如果存在索引,这两个查询都将在(开始、结束)上使用索引。

票数 2
EN

Stack Overflow用户

发布于 2011-04-06 14:16:29

把它们放在一个排序的列表中。标记排序列表中的哪些元素表示范围开始,哪些表示范围结束。首先根据值对列表进行排序;但是,确保范围在范围结束之前就开始了。(这可能涉及某种可以在给定密钥上排序的结构。我不知道php中的细节。)

现在,从头到尾遍历列表。留个柜台,c。当您通过范围开始时,增量c。当您通过范围结束时,减少c

c从0到1时,这是最后一组范围的开始。当c从1到0时,这就是范围的结束。

编辑::如果您已经在某个数据库表中有了范围,您可能可以构造一个SQL查询来执行上面的第一步(同样,确保在范围结束点之前返回范围起始点)。

票数 2
EN

Stack Overflow用户

发布于 2011-04-06 14:22:42

下面是一个简单的实现:

代码语言:javascript
运行
复制
// I picked this format because it's convenient for the solution
// and because it's very natural for a human to read/write
$ranges = array(
  9    =>    12,
  1    =>    2,
  60   =>    81,
  10   =>    11,
  79   =>    88);

ksort($ranges);
$count = count($ranges);
$prev = null; // holds the previous start-end pair

foreach($ranges as $start => $end) {
    // If this range overlaps or is adjacent to the previous one
    if ($prev !== null && $start <= $prev[1] + 1) {
        // Update the previous one (both in $prev and in $ranges)
        // to the union of its previous value and the current range
        $ranges[$prev[0]] = $prev[1] = max($end, $prev[1]);

        // Mark the current range as "deleted"
        $ranges[$start] = null;
        continue;
    }

    $prev = array($start, $end);
}

// Filter all "deleted" ranges out
$ranges = array_filter($ranges);

限制/说明:

  1. 范围边界必须足够小,以适应一个int
  2. 如果结束边界为0,则此示例将错误地从最终结果中删除任何范围。如果您的数据能够合法地包含这样的范围,则提供对array_filterfunction($item) { return $item === null; }的适当回调。

看到它的行动

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5567621

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档