MariaDB ColumnStore: фильтрация подзапроса по вычисляемому значению

У меня есть таблица, в которой для данного кортежа (time, country, asn) хранится несколько показателей:

+----------+---------+-------+-------+--------+--------+
|   time   | country |  asn  |  rtt  |  rexb  |  reqs  |
+----------+---------+-------+-------+--------+--------+
| 10000000 |   US    | 12345 |  40   |  0.05  |  5000  |
| 10000000 |   US    | 54321 |  120  |  0.15  |  500   |
| 10000000 |   MX    | 12345 |  300  |  0.25  |  1000  |
| 10000000 |   MX    | 54321 |  160  |  0.10  |  200   |
|   ....   |   ...   |  ...  |  ...  |  ....  |  ....  |

При обычном использовании я нормализую каждую из этих метрик до значения от 0 до 100, затем возвращаю наибольшее значение, чтобы получить приблизительную оценку того, «насколько хорошо» соединение с этим ASN в этой стране:

SELECT
    country,
    asn,
    least(
        -- least(100, greatest(0, ...)) = clip value between 0 and 100
        least(100, greatest(0,
            -- normalize and protect against null values
            -- sample normalization:
            --     0 ms RTT = "100% good"
            --     300 ms RTT = "0% good"
            coalesce((300 - rtt) / 3, 0)
        )),
        least(100, greatest(0,
            -- sample normalization:
            --     0% REXB = "100% good"
            --     50% REXB = "0% good"
            coalesce((0.5 - rexb) / 0.5, 0)
        )),
        -- Other metrics may follow
    ) as quality
FROM
    metrics
WHERE
    time = 10000000 -- "current time"

Иногда я могу вычислить средневзвешенные значения, используя для взвешивания столбец reqs (количество запросов в эту страну + ASN):

SELECT
    country,
    least(
        least(100, greatest(0,
            coalesce((300 - sum(rtt*reqs)/sum(reqs)) / 3, 0)
        )),
        least(100, greatest(0,
            coalesce((0.5 - sum(rexb*reqs)/sum(reqs)) / 0.5, 0)
        ))
    ) as avg_quality
FROM
    metrics
WHERE
    time = 10000000 -- "current time"
GROUP BY
    country

Этот запрос работает отлично. Однако я столкнулся с проблемой, когда попытался использовать это в подзапросе.

Моя цель состояла в том, чтобы найти, сколько стран имеют «среднее качество» ниже определенного порога:

SELECT 
    count(*)
FROM (
    SELECT
        country,
        least(
            least(100, greatest(0,
                coalesce((300 - sum(rtt*reqs)/sum(reqs)) / 3, 0)
            )),
            least(100, greatest(0,
                coalesce((0.5 - sum(rexb*reqs)/sum(reqs)) / 0.5, 0)
            ))
        ) as avg_quality
    FROM
        metrics
    WHERE
        time = 10000000 -- "current time"
    GROUP BY
        time, country
) t1
WHERE t1.avg_quality < 50

Это вызвало ошибку:

ERROR 1815 (HY000): Internal error: Lost connection to ExeMgr. Please contact your administrator

Я могу выполнять более простые подзапросы без проблем. Почему этот не работает и как это исправить?

Я использую MariaDB, а таблица metrics использует движок ColumnStore.

Быстрое обновление

Когда я заменяю WHERE t1.avg_quality < 50 на WHERE country = "US", запрос выполняется без проблем. Таким образом, у него нет проблем с выполнением подзапроса или фильтрации. Строго, когда я пытаюсь отфильтровать вычисляемый столбец, он терпит неудачу.


person stevendesu    schedule 26.02.2018    source источник


Ответы (1)


Я связался с администраторами баз данных в моей компании, чтобы узнать, есть ли у них какие-либо ответы или предложения. Они не смогли объяснить такое поведение, но смогли предложить обходной путь:

SELECT 
    count(*)
FROM (
    SELECT
        country,
        least(
            least(100, greatest(0,
                coalesce((300 - sum(rtt*reqs)/sum(reqs)) / 3, 0)
            )),
            least(100, greatest(0,
                coalesce((0.5 - sum(rexb*reqs)/sum(reqs)) / 0.5, 0)
            ))
        ) as avg_quality
    FROM
        metrics
    WHERE
        time = 10000000 -- "current time"
    GROUP BY
        time, country
    HAVING
        avg_quality < 50
) t1
person stevendesu    schedule 27.02.2018