sql优化建议

sql优化建议
SELECT count(*) FROM fsrs_cards WHERE fsrs_cards.deleted_at IS NULL and exist (select 1 from vocab_words where vocab_id 1001 and obj_id word_id and deleted_at is null) AND (user_id 1983799923358830592) AND (要分析这条SQL查询我需要先指出语法错误然后解释查询意图最后给出优化建议。语法错误exist应该是EXISTS关键字拼写错误正确写法sqlSELECT count(*) FROM fsrs_cards WHERE fsrs_cards.deleted_at IS NULL AND EXISTS ( SELECT 1 FROM vocab_words WHERE vocab_id 1001 AND obj_id word_id AND deleted_at IS NULL ) AND (user_id 1983799923358830592) AND (ctype words) AND (word_history_type 10)查询意图统计满足以下条件的fsrs_cards记录数量未被删除deleted_at IS NULL用户ID为特定值卡片类型为words单词历史类型为10存在对应的vocab_words记录vocab_id 1001且obj_id匹配word_id且未被删除潜在问题1. 子查询与主查询缺乏关联子查询中的word_id来自vocab_words表但它与主查询的fsrs_cards表没有任何关联条件。这意味着如果vocab_words表中至少存在一条满足条件的记录子查询就返回 true所有符合条件的fsrs_cards都会被计数如果不存在则计数为 0这可能是逻辑错误你可能想要的是关联子查询sql-- 如果 fsrs_cards 有 word_id 字段 SELECT count(*) FROM fsrs_cards WHERE fsrs_cards.deleted_at IS NULL AND EXISTS ( SELECT 1 FROM vocab_words WHERE vocab_id 1001 AND obj_id fsrs_cards.word_id -- 关联到主表 AND deleted_at IS NULL ) AND (user_id 1983799923358830592) AND (ctype words) AND (word_history_type 10)2. 索引建议为了优化性能建议创建以下索引sql-- fsrs_cards 表 CREATE INDEX idx_fsrs_cards_user_ctype_history ON fsrs_cards(user_id, ctype, word_history_type, deleted_at); -- vocab_words 表如果还没有 CREATE INDEX idx_vocab_words_vocab_obj ON vocab_words(vocab_id, obj_id, deleted_at);3. 如果确实是存在性检查而非关联如果你的意图确实是不需要关联只要vocab_words中有一条vocab_id1001的记录就计数所有卡那查询逻辑没问题但可以改用更高效的写法sqlSELECT count(*) FROM fsrs_cards WHERE fsrs_cards.deleted_at IS NULL AND (user_id 1983799923358830592) AND (ctype words) AND (word_history_type 10) AND EXISTS ( SELECT 1 FROM vocab_words WHERE vocab_id 1001 AND deleted_at IS NULL LIMIT 1 -- 找到一条就停 );总结问题说明语法错误exist→EXISTS逻辑问题子查询未关联主表可能不是你想要的结果性能优化需要合适的索引特别是user_idctypeword_history_type请确认你的业务逻辑是否需要关联fsrs_cards.word_id如果需要请按修正后的关联子查询写法调整。ctype words ) AND (word_history_type 10)

最新新闻

日新闻

周新闻

月新闻