CQL SÉLECTIONNEZ supérieur de la requête sur l'indexation non-colonne de clé
EDIT1: ajout d'un cas à décrire le problème après la question d'origine.
Je souhaite interroger sur une colonne qui ne fait pas partie de ma clé. Si je comprends bien, j'ai besoin de définir un index secondaire sur cette colonne. Cependant, je souhaite utiliser un plus grand que la condition (pas seulement la condition d'égalité) et qui semble toujours pas pris en charge.
Suis-je raté quelque chose?
Comment voulez-vous résoudre ce problème?
Ma Configuration souhaitée:
Cassandra 1.1.6
CQL3
CREATE TABLE Table1(
KeyA int,
KeyB int,
ValueA int,
PRIMARY KEY (KeyA, KeyB)
);
CREATE INDEX ON Table1 (ValueA);
SELECT * FROM Table1 WHERE ValueA > 3000;
Depuis la définition d'un index secondaire sur ColumnFamilies avec des Clés Composites est toujours pas pris en charge dans Cassandra 1.1.6-je régler le solde sur une solution temporaire de décrocher l'une des clés, mais j'ai toujours le même problème avec la non égalité de conditions.
Est-il une autre façon de régler ce problème?
Je vous remercie pour votre temps.
Sources pertinentes:
http://cassandra.apache.org/doc/cql3/CQL.html#selectStmt
http://www.datastax.com/docs/1.1/ddl/indexes
EDIT1
Voici un cas qui va vous expliquer le problème. Comme rs-atl noté, il pourrait être un modèle de données d'un problème. Disons que je garde une colonne de la famille de tous les utilisateurs sur stackoverflow. pour chaque utilisateur je garde un lot de stats (Réputation, NumOfAnswers, NumOfVotes... ils sont tous de type int). Je veux interroger sur ces stats pour obtenir des utilisateurs concernés.
CREATE TABLE UserStats(
UserID int,
Reputation int,
NumOfAnswers int,
.
.
.
A lot of stats...
.
.
.
NumOfVotes int,
PRIMARY KEY (UserID)
);
Maintenant, je suis intéressé dans de découpage UserID est basé sur ces stats. Je veux que tous les utilisateurs avec plus de 10K réputation, je veux que tous les utilisateurs avec moins de 5 réponses, etc. etc.
J'espère que ça aide. Merci encore.
Tout d'abord, merci d'avoir accepté de l'aider. Je vais modifier mon post et de décrire un cas simple qui s'adapte le problème. Si vous êtes intéressé par mon modèle de conception, vous pouvez le trouver ici: stackoverflow.com/questions/13131254/... La colonne correspondante de la famille pour cette question est TestsData.
Vous savez à l'avance ce que les colonnes dont vous aurez besoin et/ou en ce que la plage de valeurs peut être, ou sont ces dynamiques?
J'ai environ 20 ou si les stats. Je vais devoir être en mesure de découper les utilisateurs sur chacun d'eux. (BTW: quand vous avez dit dynamique, vous dire que les colonnes? Je n'attends pas beaucoup de nouvelles statistiques, cette famille de colonne est assez statique)
OriginalL'auteur Oren | 2012-11-27
Vous devez vous connecter pour publier un commentaire.
En CQL, vous êtes en mesure d'appliquer la
WHERE
clause sur toutes les colonnes, une fois que vous avez créé indices pour eux (c'est à dire, index secondaire). Sinon, vous obtiendrez l'erreur suivante:Malheureusement, même avec les indices, la clause where sont tenus d'avoir au moins un EQ sur un index secondaire par CQL en raison de problème de performance.
Donc, fondamentalement, si vous avez quelque chose en plus d'un ÉGALISEUR de comparaison, il se charge de toutes les lignes "que elsewise match" à votre requête, et vérifie si elles correspondent, un à la fois. Ce qui n'est pas autorisé par défaut car il "peut être très lente." (En substance, les index seulement l'index "pour l'égalité" pas pour autre chose comme < et > index sur une base de données relationnelle serait).
Une chose à noter est que si vous avez plus d'un non ÉGALISATION des conditions sur les indices, vous devez également inclure le
ALLOW FILTERING
mot-clé dans votre requête, ou bien vous allez obtenirCannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING
La manière la plus simple de contourner cette difficulté est d'ajouter un mannequin de la colonne de votre table, où toutes les lignes ont la même valeur sur cette colonne. Dans ce cas, vous êtes en mesure d'effectuer variait de requête sur votre colonne souhaitée. Faire réaliser que ce genre de requêtes sur une base de données NoSQL peut être lent/bog bas un système.
Exemple
Créer secondaire indices sur ValueA et DummyValue:
Allaient effectuer de requête sur
ValueA
avecDummyValue=0
:D'autre part, c'est une très MAUVAISE solution. Selon les docs: "la création d'un index sur une très faible cardinalité de la colonne, comme une valeur booléenne de la colonne, n'a pas de sens. Chaque valeur dans l'indice devient une seule ligne dans l'index, ce qui entraîne un énorme ligne pour toutes les fausses valeurs, par exemple. L'indexation d'une multitude de colonnes indexées avoir foo = true et foo = false n'est pas utile." datastax.com/documentation/cql/3.0/webhelp/index.html#cql/ddl/...
Oui, c'est une mauvaise solution car elle les abus de l'indice dans une façon très lent. Idéalement, Cassandra, les utilisateurs devraient éviter ce type de requêtes que Cassandra n'ont actuellement pas de bonne façon de le gérer.
OriginalL'auteur keelar
Probablement le moyen le plus souple pour faire face à ce scénario dans Cassandra sera d'avoir un CF pour chaque stat, avec sentinel valeurs clés et de l'état de la valeur dans la colonne nom, comme ceci:
Donc, disons que votre stat est NumAnswers et votre Id d'utilisateur sont des chaînes de caractères:
De sorte que vous pouvez voir que vos clés sont essentiellement des seaux de valeurs, qui peuvent être aussi grossier ou fin de grains nécessaires pour vos données et de vos colonnes sont des composites de valeur + ID d'utilisateur. Vous pouvez désormais main de Cassandra connu une clé (ou un ensemble de touches) pour le gros de la gamme dont vous avez besoin (l'égalité), puis faire une requête de plage sur le premier élément de la colonne nom. Notez que vous ne peut pas écrire l'ID de l'utilisateur comme valeur, parce que cela permettrait d'éviter deux utilisateurs d'avoir le même nombre de.
OriginalL'auteur rs_atl
CLÉ PRIMAIRE (KeyA, KeyB)
);
CRÉER un INDEX SUR la table Table1 (ValueA);
SELECT * from Table1 OÙ ValueA > 3000;
La
Cassandra way
est d'avoir une clé de partition et toujours l'utiliser, avec un regroupement de colonne pourValueA
éventuellementPRIMARY KEY ((KeyA, KeyB), ValueA)
et ensuite utiliser comme:select * from Table1 where KeyA='xx' and ValueA > 3000
OriginalL'auteur rogerdpack