Hi everyone. I’m stuck with a slow query I’d like ...
# prisma-client
y
Hi everyone. I’m stuck with a slow query I’d like to speed up. TLDR; this query is super slow. What should I do to speed this query up? Can I do it by adding an index?
Copy code
prisma.concept.findMany({
    where: {
      dictionaryId: Number(dictId),
      name: {contains: foo}
    },
    include: {
      _count: {
        select: {
          declarations: true, // including this in the query makes it super slow
        },
      },
    }
  })
I have a concept table and a declaration table. Concept and declaration have a many to many relationship. The declaration table has more than 500k rows, same goes for concept table. longer explanation: https://www.loom.com/share/ff8d3034898e4ad08b8d19f044d500fe
j
@Yann Buydens can you drop your db schema in here?
y
@Jeremy Hinegardner
Copy code
model Concept {
  id                                     Int                                @id @default(autoincrement())
  createdAt                              DateTime                           @default(now())
  updatedAt                              DateTime                           @updatedAt
  name                                   String                             @db.VarChar(255)
  definition                             String?
  declarations                           Declaration[]                      @relation(references: [id])
  tags                                   Tag[]                              @relation(references: [id])
  dictionary                             Dictionary                         @relation(fields: [dictionaryId], references: [id], onDelete: Cascade)
  dictionaryId                           Int
  ignore                                 Boolean?                           @default(false)
  conceptValidation                      ConceptValidation?
  DeltaAnalysisResult                    DeltaAnalysisResult?               @relation(fields: [deltaAnalysisResultId], references: [id])
  deltaAnalysisResultId                  String?
  deltaAnalysisResultsWhereConsideredNew NewConceptsInDeltaAnalysisResult[]

  @@unique([name, dictionaryId])
}

model Declaration {
  id          String    @id @default(cuid())
  name        String    @db.VarChar(255)
  concepts    Concept[] @relation(references: [id])
  location    Location  @relation(fields: [locationId], references: [id])
  locationId  String
  repo_url    String
  branch_name String
  commit_hash String
  tags        Tag[]     @relation(references: [id])
}
thx for helping me out 🙏 appreciate it
j
@Yann Buydens - I think the raw database schema would be more helpful - it looks like you are using an implicit many-to-many relationship between
concept
and
declaration
so there is a join table under the covers, and I'd want to look and see if there are indexes on it.
y
ok. @Jeremy Hinegardner is this what you need?
Copy code
-- DDL generated by Postico 1.5.20
-- Not all database features are supported. Do not use for backup.

-- Table Definition ----------------------------------------------

CREATE TABLE "_ConceptToDeclaration" (
    "A" integer NOT NULL REFERENCES "Concept"(id) ON DELETE CASCADE ON UPDATE CASCADE,
    "B" text NOT NULL REFERENCES "Declaration"(id) ON DELETE CASCADE ON UPDATE CASCADE
);

-- Indices -------------------------------------------------------

CREATE UNIQUE INDEX "_ConceptToDeclaration_AB_unique" ON "_ConceptToDeclaration"("A" int4_ops,"B" text_ops);
CREATE INDEX "_ConceptToDeclaration_B_index" ON "_ConceptToDeclaration"("B" text_ops);
Copy code
-- DDL generated by Postico 1.5.20
-- Not all database features are supported. Do not use for backup.

-- Table Definition ----------------------------------------------

CREATE TABLE "Concept" (
  id integer DEFAULT nextval('"Concept_id_seq"'::regclass) PRIMARY KEY,
  "createdAt" timestamp(3) without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "updatedAt" timestamp(3) without time zone NOT NULL,
  name character varying(255) NOT NULL,
  definition text,
  "dictionaryId" integer NOT NULL REFERENCES "Dictionary"(id) ON DELETE CASCADE ON UPDATE CASCADE,
  ignore boolean DEFAULT false,
  "deltaAnalysisResultId" text REFERENCES "DeltaAnalysisResult"(id) ON DELETE SET NULL ON UPDATE CASCADE
);

-- Indices -------------------------------------------------------

CREATE UNIQUE INDEX "Concept_pkey" ON "Concept"(id int4_ops);
CREATE UNIQUE INDEX "Concept_name_dictionaryId_key" ON "Concept"(name text_ops,"dictionaryId" int4_ops);
Copy code
-- DDL generated by Postico 1.5.20
-- Not all database features are supported. Do not use for backup.

-- Table Definition ----------------------------------------------

CREATE TABLE "Declaration" (
    id text PRIMARY KEY,
    name character varying(255) NOT NULL,
    "locationId" text NOT NULL REFERENCES "Location"(id) ON DELETE RESTRICT ON UPDATE CASCADE,
    repo_url text NOT NULL,
    branch_name text NOT NULL,
    commit_hash text NOT NULL
);

-- Indices -------------------------------------------------------

CREATE UNIQUE INDEX "Declaration_pkey" ON "Declaration"(id text_ops);
j
@Yann Buydens The join table in the middle that has concept_id and dictionary_id would be good to kno, but the concept table now has a dictionary_id in it, but it would probably be better if the dictionaryId as the first element of the index instead of the 2nd. That index won't get used unless there is also a name in the query. the join tqable between concept and diationary should have an index on both the dicationaryId and conceptId columns outsidce of that I'd ahve to see the live query that you have to do anything else. I'm heading on vacation for a couple of weeks, so unfrotunately I'll be very slow to respond. I hope this has helped a little bit, and totally understand if it hasn't
y
@Jeremy Hinegardner have fun on vacation! and thanks for the help. I’ll try to figure it out