Considering the (simplified) table that I wrote before:

create table data (
id bigint,
ts bigint,
column1 blob,
column2 blob,
column3 blob,
...
column29 blob,
column30 blob
primary key (id, ts)

A user request (varies every time) translates into a set of queries asking
a subset of the columns (< 10) for a specific set of sensors (< 100) for a
specific time range (< 300):

SELECT column1, column7, column20, column25 FROM data where id =
SENSOR_ID_1 and ts > x and ts < y)
SELECT column1, column7, column20, column25 FROM data where id =
SENSOR_ID_2 and ts > x and ts < y)
...
SELECT column1, column7, column20, column25 FROM data where id =
SENSOR_ID_N and ts > x and ts < y)

To answer your question, each non-EQ predicate on timestamp returns a few
hundreds rows (it's essentially a time series).

If I put the column number as clustering key with the timestamp, I'll have
to further increase the number of queries and make my code more complicated:

SELECT value FROM data where id = SENSOR_ID_1 and ts > x and ts < y and
column_number = 1)
SELECT value FROM data where id = SENSOR_ID_1 and ts > x and ts < y and
column_number = 7)
SELECT value FROM data where id = SENSOR_ID_1 and ts > x and ts < y and
column_number = 20)
SELECT value FROM data where id = SENSOR_ID_1 and ts > x and ts < y and
column_number = 25)
...

Again, not too terrible and I'll definitely have to do something similar
because the performance penalty I'm paying now is very significant, but by
all means this seems to me a complication in the data model (and in my
application).

Thanks again


On Sun, Feb 14, 2016 at 5:21 PM, Jack Krupansky <jack.krupan...@gmail.com>
wrote:

> What does your query actually look like today?
>
> Is your non-EQ on timestamp selecting a single row a few rows or many rows
> (dozens, hundreds, thousands)?
>
>
> -- Jack Krupansky
>
> On Sun, Feb 14, 2016 at 7:40 PM, Gianluca Borello <gianl...@sysdig.com>
> wrote:
>
>> Thanks again.
>>
>> One clarification about "reading in a single SELECT": in my point 2, I
>> mentioned the need to read a variable subset of columns every time, usually
>> in the range of ~5 out of 30. I can't find a way to do that in a single
>> SELECT unless I use the IN operator (which I can't, as explained).
>>
>> Is there any other method you were thinking of, or your "reading in a
>> single SELECT" is just applicable when I need to read the whole set of
>> columns (which is never my case, unfortunately)?
>>
>> Thanks
>>
>>
>> On Sun, Feb 14, 2016 at 4:34 PM, Jack Krupansky <jack.krupan...@gmail.com
>> > wrote:
>>
>>> You can definitely read all of columns in a single SELECT. And the
>>> n-INSERTS can be batched and will insert fewer cells in the storage engine
>>> than the previous approach.
>>>
>>> -- Jack Krupansky
>>>
>>> On Sun, Feb 14, 2016 at 7:31 PM, Gianluca Borello <gianl...@sysdig.com>
>>> wrote:
>>>
>>>> Thank you for your reply.
>>>>
>>>> Your advice is definitely sound, although it still seems suboptimal to
>>>> me because:
>>>>
>>>> 1) It requires N INSERT queries from the application code (where N is
>>>> the number of columns)
>>>>
>>>> 2) It requires N SELECT queries from my application code (where N is
>>>> the number of columns I need to read at any given time, which is determined
>>>> at runtime). I can't even use the IN operator (e.g. WHERE column_number IN
>>>> (1, 2, 3, ...)) because I am already using a non-EQ relation on the
>>>> timestamp key and Cassandra restricts me to only one non-EQ relation.
>>>>
>>>> In summary, I can (and will) adapt my code to use a similar approach
>>>> despite everything, but the goal of my message was mainly to understand why
>>>> the jira issues I linked above are not full of dozens of "+1" comments.
>>>>
>>>> To me this really feels like a terrible performance issue that should
>>>> be fixed by default (or in the very worst case clearly documented), even
>>>> after understanding the motivation for reading all the columns in the CQL
>>>> row.
>>>>
>>>> Thanks
>>>>
>>>> On Sun, Feb 14, 2016 at 3:05 PM, Jack Krupansky <
>>>> jack.krupan...@gmail.com> wrote:
>>>>
>>>>> You could add the column number as an additional clustering key. And
>>>>> then you can actually use COMPACT STORAGE for even more efficient storage
>>>>> and access (assuming there is only  a single non-PK data column, the blob
>>>>> value.) You can then access (read or write) an individual column/blob or a
>>>>> slice of them.
>>>>>
>>>>> -- Jack Krupansky
>>>>>
>>>>> On Sun, Feb 14, 2016 at 5:22 PM, Gianluca Borello <gianl...@sysdig.com
>>>>> > wrote:
>>>>>
>>>>>> Hi
>>>>>>
>>>>>> I've just painfully discovered a "little" detail in Cassandra:
>>>>>> Cassandra touches all columns on a CQL select (related issues
>>>>>> https://issues.apache.org/jira/browse/CASSANDRA-6586,
>>>>>> https://issues.apache.org/jira/browse/CASSANDRA-6588,
>>>>>> https://issues.apache.org/jira/browse/CASSANDRA-7085).
>>>>>>
>>>>>> My data model is fairly simple: I have a bunch of "sensors" reporting
>>>>>> a blob of data (~10-100KB) periodically. When reading, 99% of the times 
>>>>>> I'm
>>>>>> interested in a subportion of that blob of data across an arbitrary 
>>>>>> period
>>>>>> of time. What I do is simply splitting those blobs of data in about 30
>>>>>> logical units and write them in a CQL table such as:
>>>>>>
>>>>>> create table data (
>>>>>> id bigint,
>>>>>> ts bigint,
>>>>>> column1 blob,
>>>>>> column2 blob,
>>>>>> column3 blob,
>>>>>> ...
>>>>>> column29 blob,
>>>>>> column30 blob
>>>>>> primary key (id, ts)
>>>>>>
>>>>>> id is a combination of the sensor id and a time bucket, in order to
>>>>>> not get the row too wide. Essentially, I thought this was a very legit 
>>>>>> data
>>>>>> model that helps me keep my application code very simple (because I can
>>>>>> work on a single table, I can write a split sensor blob in a single CQL
>>>>>> query and I can read a subset of the columns very efficiently with one
>>>>>> single CQL query).
>>>>>>
>>>>>> What I didn't realize is that Cassandra seems to always process all
>>>>>> the columns of the CQL row, regardless of the fact that my query asks 
>>>>>> just
>>>>>> one column, and this has dramatic effect on the performance of my reads.
>>>>>>
>>>>>> I wrote a simple isolated test case where I test how long it takes to
>>>>>> read one *single* column in a CQL table composed of several columns (at
>>>>>> each iteration I add and populate 10 new columns), each filled with 1MB
>>>>>> blobs:
>>>>>>
>>>>>> 10 columns: 209 ms
>>>>>> 20 columns: 339 ms
>>>>>> 30 columns: 510 ms
>>>>>> 40 columns: 670 ms
>>>>>> 50 columns: 884 ms
>>>>>> 60 columns: 1056 ms
>>>>>> 70 columns: 1527 ms
>>>>>> 80 columns: 1503 ms
>>>>>> 90 columns: 1600 ms
>>>>>> 100 columns: 1792 ms
>>>>>>
>>>>>> In other words, even if the result set returned is exactly the same
>>>>>> across all these iteration, the response time increases linearly with the
>>>>>> size of the other columns, and this is really causing a lot of problems 
>>>>>> in
>>>>>> my application.
>>>>>>
>>>>>> By reading the JIRA issues, it seems like this is considered a very
>>>>>> minor optimization not worth the effort of fixing, so I'm asking: is my 
>>>>>> use
>>>>>> case really so anomalous that the horrible performance that I'm
>>>>>> experiencing are to be considered "expected" and need to be fixed with 
>>>>>> some
>>>>>> painful column family splitting and messy application code?
>>>>>>
>>>>>> Thanks
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>

Reply via email to