#Compare v.union() performance of v.literal() versus v.number()

7 messages · Page 1 of 1 (latest)

mighty juniper
#

In Convex is the read and write database performance and bandwidth use better if I use
A) v.union() of multiple v.literal('someString')

So for example,
// convex/schema.ts
import { v } from "convex/values";
import { defineSchema, defineTable } from "convex/server";

export default defineSchema({
recipes: defineTable({
name: v.string(),
course: v.union(
v.literal('appetizer'),
v.literal('main'),
v.literal('dessert')
),
ingredients: v.array(v.string()),
steps: v.array(v.string())
}).index("by_course", ["course"]),
});

Or,
B) v.union() of multiple v.number(), i.e. 0,1,2, and just document somewhere that 0 means appetizer, 1 means main, and 2 means dessert.

pure elkBOT
#

Hi @mighty juniper. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

In terms of performance, the Convex documentation and knowledge sources do not provide specific information on the performance difference between using v.union() with v.literal() versus v.number().

However, in a Discord support thread (https://discord.com/channels/1019350475847499849/1272890661636673666), a Convex staff member mentioned that changing schema to use numbers instead of strings could potentially reduce database bandwidth. This suggests that using v.number() might be more efficient in terms of bandwidth usage.

That being said, it's important to consider the readability and maintainability of your code. Using v.literal() with meaningful string values can make your code more self-explanatory, while using v.number() with arbitrary numeric codes might require additional documentation and could potentially lead to confusion.

Here's how you might define your schema using v.number():

// convex/schema.ts
import { v } from "convex/values";
import { defineSchema, defineTable } from "convex/server";

export default defineSchema({
  recipes: defineTable({
    name: v.string(),
    course: v.union(
      v.number(0), 
      v.number(1),
      v.number(2)
    ),
    ingredients: v.array(v.string()),
    steps: v.array(v.string())
  }).index("by_course", ["course"]),
});

In this case, you would need to document that 0 represents 'appetizer', 1 represents 'main', and 2 represents 'dessert'.

In conclusion, while using v.number() might potentially offer some performance benefits, you should also consider the trade-off in terms of code readability and maintainability.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@mighty juniper kapa.ai is still learning and improving, please let us know how it did by reacting below

mighty juniper
#

@pure elk Tell me about the index design for each approach. If I v.union() with v.literal(), do I essentially have to add an index to the course column? And if I v.union() with .number(), is an index unnecessary and not that helpful?

pure elkBOT
#

Let me check the knowledge base for you. One moment! :books:

#

In Convex, indexes are used to optimize the performance of queries that filter or sort data based on specific fields. Regardless of whether you use v.union() with v.literal() or v.number(), you would likely want to add an index to the course field if you plan to perform queries that filter or sort data based on this field.

Here's how you might define an index on the course field:

// convex/schema.ts
import { v } from "convex/values";
import { defineSchema, defineTable } from "convex/server";

export default defineSchema({
  recipes: defineTable({
    name: v.string(),
    course: v.union(
      v.literal('appetizer'), 
      v.literal('main'),
      v.literal('dessert')
    ),
    ingredients: v.array(v.string()),
    steps: v.array(v.string())
  }).index("by_course", ["course"]),
});

In this example, an index named by_course is created on the course field. This would optimize queries that filter or sort data based on the course field.

The type of the field (v.literal() or v.number()) does not directly affect the need for an index. The need for an index is primarily determined by the types of queries you plan to perform. If you frequently perform queries that filter or sort data based on the course field, then an index on this field would likely be beneficial regardless of whether the field is defined using v.literal() or v.number().

For more information on indexes in Convex, you can refer to the Convex documentation (https://docs.convex.dev/database/schemas#indexes).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: