[{"data":1,"prerenderedAt":986},["ShallowReactive",2],{"guide-sql-query-optimization":3},{"id":4,"title":5,"body":6,"date":975,"description":976,"extension":977,"meta":978,"navigation":196,"path":982,"readingTime":212,"seo":983,"stem":984,"__hash__":985},"guides\u002Fguides\u002Fsql-query-optimization.md","SQL Query Optimization: Performance Tips for Faster Queries",{"type":7,"value":8,"toc":955},"minimark",[9,14,18,21,25,28,33,81,84,113,117,147,173,177,220,223,227,230,239,242,305,308,322,325,329,332,338,416,421,425,428,455,458,506,509,513,516,555,558,572,576,579,630,633,699,703,706,756,759,780,783,847,850,865,868,872,895,899,918,922,931,935,951],[10,11,13],"h2",{"id":12},"why-query-performance-matters","Why Query Performance Matters",[15,16,17],"p",{},"A slow query does not just waste time — it cascades. One unoptimized query locks rows longer, consumes connection pool slots, and delays every other request hitting the same database. Under load, three poorly tuned queries can bring down an entire service.",[15,19,20],{},"The good news: most slow queries share the same small set of root causes. Learn to spot them, and you fix the majority of your performance problems.",[10,22,24],{"id":23},"reading-explain-plans","Reading EXPLAIN Plans",[15,26,27],{},"Every database provides a way to see its execution plan before running the query. This is your primary diagnostic tool.",[29,30,32],"h3",{"id":31},"postgresql","PostgreSQL",[34,35,40],"pre",{"className":36,"code":37,"language":38,"meta":39,"style":39},"language-sql shiki shiki-themes github-light github-dark","EXPLAIN ANALYZE\nSELECT u.name, COUNT(o.id)\nFROM users u\nJOIN orders o ON u.id = o.user_id\nWHERE o.created_at > '2024-01-01'\nGROUP BY u.name;\n","sql","",[41,42,43,51,57,63,69,75],"code",{"__ignoreMap":39},[44,45,48],"span",{"class":46,"line":47},"line",1,[44,49,50],{},"EXPLAIN ANALYZE\n",[44,52,54],{"class":46,"line":53},2,[44,55,56],{},"SELECT u.name, COUNT(o.id)\n",[44,58,60],{"class":46,"line":59},3,[44,61,62],{},"FROM users u\n",[44,64,66],{"class":46,"line":65},4,[44,67,68],{},"JOIN orders o ON u.id = o.user_id\n",[44,70,72],{"class":46,"line":71},5,[44,73,74],{},"WHERE o.created_at > '2024-01-01'\n",[44,76,78],{"class":46,"line":77},6,[44,79,80],{},"GROUP BY u.name;\n",[15,82,83],{},"Key things to look for:",[85,86,87,95,101,107],"ul",{},[88,89,90,94],"li",{},[91,92,93],"strong",{},"Seq Scan"," — the database reads the entire table. Acceptable for small tables, a problem for large ones.",[88,96,97,100],{},[91,98,99],{},"Index Scan"," — the database uses an index. This is what you want for large filtered queries.",[88,102,103,106],{},[91,104,105],{},"Nested Loop"," — fine for small result sets, expensive for large ones.",[88,108,109,112],{},[91,110,111],{},"Hash Join \u002F Merge Join"," — better for joining large tables.",[29,114,116],{"id":115},"mysql","MySQL",[34,118,120],{"className":36,"code":119,"language":38,"meta":39,"style":39},"EXPLAIN\nSELECT u.name, COUNT(o.id)\nFROM users u\nJOIN orders o ON u.id = o.user_id\nWHERE o.created_at > '2024-01-01'\nGROUP BY u.name;\n",[41,121,122,127,131,135,139,143],{"__ignoreMap":39},[44,123,124],{"class":46,"line":47},[44,125,126],{},"EXPLAIN\n",[44,128,129],{"class":46,"line":53},[44,130,56],{},[44,132,133],{"class":46,"line":59},[44,134,62],{},[44,136,137],{"class":46,"line":65},[44,138,68],{},[44,140,141],{"class":46,"line":71},[44,142,74],{},[44,144,145],{"class":46,"line":77},[44,146,80],{},[15,148,149,150,153,154,157,158,161,162,165,166,161,169,172],{},"Check the ",[41,151,152],{},"type"," column: ",[41,155,156],{},"ALL"," means a full table scan. ",[41,159,160],{},"ref"," or ",[41,163,164],{},"range"," means index usage. ",[41,167,168],{},"Extra: Using filesort",[41,170,171],{},"Using temporary"," signals expensive operations.",[29,174,176],{"id":175},"sql-server","SQL Server",[34,178,180],{"className":36,"code":179,"language":38,"meta":39,"style":39},"SET STATISTICS IO ON;\nSET STATISTICS TIME ON;\n\nSELECT u.name, COUNT(o.id)\nFROM users u\nJOIN orders o ON u.id = o.user_id\nWHERE o.created_at > '2024-01-01'\nGROUP BY u.name;\n",[41,181,182,187,192,198,202,206,210,215],{"__ignoreMap":39},[44,183,184],{"class":46,"line":47},[44,185,186],{},"SET STATISTICS IO ON;\n",[44,188,189],{"class":46,"line":53},[44,190,191],{},"SET STATISTICS TIME ON;\n",[44,193,194],{"class":46,"line":59},[44,195,197],{"emptyLinePlaceholder":196},true,"\n",[44,199,200],{"class":46,"line":65},[44,201,56],{},[44,203,204],{"class":46,"line":71},[44,205,62],{},[44,207,208],{"class":46,"line":77},[44,209,68],{},[44,211,213],{"class":46,"line":212},7,[44,214,74],{},[44,216,218],{"class":46,"line":217},8,[44,219,80],{},[15,221,222],{},"Focus on logical reads — the number of 8 KB pages read. Lower is better.",[10,224,226],{"id":225},"how-formatting-reveals-performance-issues","How Formatting Reveals Performance Issues",[15,228,229],{},"Well-formatted SQL makes performance problems visible. Consider this unformatted query:",[34,231,233],{"className":36,"code":232,"language":38,"meta":39,"style":39},"select * from orders o join customers c on o.customer_id=c.id join order_items oi on o.id=oi.order_id join products p on oi.product_id=p.id where o.status='pending' and c.country='US' and p.category='Electronics';\n",[41,234,235],{"__ignoreMap":39},[44,236,237],{"class":46,"line":47},[44,238,232],{},[15,240,241],{},"Hard to read, harder to optimize. Now format it:",[34,243,245],{"className":36,"code":244,"language":38,"meta":39,"style":39},"SELECT *\nFROM orders o\nJOIN customers c\n    ON o.customer_id = c.id\nJOIN order_items oi\n    ON o.id = oi.order_id\nJOIN products p\n    ON oi.product_id = p.id\nWHERE o.status = 'pending'\n    AND c.country = 'US'\n    AND p.category = 'Electronics';\n",[41,246,247,252,257,262,267,272,277,282,287,293,299],{"__ignoreMap":39},[44,248,249],{"class":46,"line":47},[44,250,251],{},"SELECT *\n",[44,253,254],{"class":46,"line":53},[44,255,256],{},"FROM orders o\n",[44,258,259],{"class":46,"line":59},[44,260,261],{},"JOIN customers c\n",[44,263,264],{"class":46,"line":65},[44,265,266],{},"    ON o.customer_id = c.id\n",[44,268,269],{"class":46,"line":71},[44,270,271],{},"JOIN order_items oi\n",[44,273,274],{"class":46,"line":77},[44,275,276],{},"    ON o.id = oi.order_id\n",[44,278,279],{"class":46,"line":212},[44,280,281],{},"JOIN products p\n",[44,283,284],{"class":46,"line":217},[44,285,286],{},"    ON oi.product_id = p.id\n",[44,288,290],{"class":46,"line":289},9,[44,291,292],{},"WHERE o.status = 'pending'\n",[44,294,296],{"class":46,"line":295},10,[44,297,298],{},"    AND c.country = 'US'\n",[44,300,302],{"class":46,"line":301},11,[44,303,304],{},"    AND p.category = 'Electronics';\n",[15,306,307],{},"Now the anti-patterns jump out:",[85,309,310,316,319],{},[88,311,312,315],{},[41,313,314],{},"SELECT *"," — fetching every column from four tables",[88,317,318],{},"Three JOINs with no index hints visible",[88,320,321],{},"Multiple WHERE conditions that might each need an index",[15,323,324],{},"Formatting does not fix performance, but it reveals where to look.",[10,326,328],{"id":327},"common-performance-anti-patterns","Common Performance Anti-Patterns",[29,330,314],{"id":331},"select",[15,333,334,335,337],{},"Never use ",[41,336,314],{}," in production queries. It pulls every column from every joined table, including ones you do not need.",[34,339,341],{"className":36,"code":340,"language":38,"meta":39,"style":39},"-- Bad: fetches 20+ columns across 4 tables\nSELECT *\nFROM orders o\nJOIN customers c ON o.customer_id = c.id\nWHERE o.status = 'shipped';\n\n-- Good: fetches only what you need\nSELECT\n    o.id,\n    o.order_date,\n    c.name,\n    c.email\nFROM orders o\nJOIN customers c ON o.customer_id = c.id\nWHERE o.status = 'shipped';\n",[41,342,343,348,352,356,361,366,370,375,380,385,390,395,401,406,411],{"__ignoreMap":39},[44,344,345],{"class":46,"line":47},[44,346,347],{},"-- Bad: fetches 20+ columns across 4 tables\n",[44,349,350],{"class":46,"line":53},[44,351,251],{},[44,353,354],{"class":46,"line":59},[44,355,256],{},[44,357,358],{"class":46,"line":65},[44,359,360],{},"JOIN customers c ON o.customer_id = c.id\n",[44,362,363],{"class":46,"line":71},[44,364,365],{},"WHERE o.status = 'shipped';\n",[44,367,368],{"class":46,"line":77},[44,369,197],{"emptyLinePlaceholder":196},[44,371,372],{"class":46,"line":212},[44,373,374],{},"-- Good: fetches only what you need\n",[44,376,377],{"class":46,"line":217},[44,378,379],{},"SELECT\n",[44,381,382],{"class":46,"line":289},[44,383,384],{},"    o.id,\n",[44,386,387],{"class":46,"line":295},[44,388,389],{},"    o.order_date,\n",[44,391,392],{"class":46,"line":301},[44,393,394],{},"    c.name,\n",[44,396,398],{"class":46,"line":397},12,[44,399,400],{},"    c.email\n",[44,402,404],{"class":46,"line":403},13,[44,405,256],{},[44,407,409],{"class":46,"line":408},14,[44,410,360],{},[44,412,414],{"class":46,"line":413},15,[44,415,365],{},[15,417,418,420],{},[41,419,314],{}," also breaks when the table schema changes — adding a column silently increases your result set size.",[29,422,424],{"id":423},"n1-queries","N+1 Queries",[15,426,427],{},"This is the most common ORM-generated performance problem. Instead of one query with a JOIN, the application runs one query to get a list, then one additional query per row.",[34,429,433],{"className":430,"code":431,"language":432,"meta":39,"style":39},"language-python shiki shiki-themes github-light github-dark","# N+1 pattern — 1 + 1000 queries\nusers = db.query(\"SELECT id, name FROM users WHERE active = true\")\nfor user in users:\n    orders = db.query(\"SELECT COUNT(*) FROM orders WHERE user_id = ?\", user.id)\n","python",[41,434,435,440,445,450],{"__ignoreMap":39},[44,436,437],{"class":46,"line":47},[44,438,439],{},"# N+1 pattern — 1 + 1000 queries\n",[44,441,442],{"class":46,"line":53},[44,443,444],{},"users = db.query(\"SELECT id, name FROM users WHERE active = true\")\n",[44,446,447],{"class":46,"line":59},[44,448,449],{},"for user in users:\n",[44,451,452],{"class":46,"line":65},[44,453,454],{},"    orders = db.query(\"SELECT COUNT(*) FROM orders WHERE user_id = ?\", user.id)\n",[15,456,457],{},"Replace with a single aggregated query:",[34,459,461],{"className":36,"code":460,"language":38,"meta":39,"style":39},"SELECT\n    u.id,\n    u.name,\n    COUNT(o.id) AS order_count\nFROM users u\nLEFT JOIN orders o\n    ON u.id = o.user_id\nWHERE u.active = true\nGROUP BY u.id, u.name;\n",[41,462,463,467,472,477,482,486,491,496,501],{"__ignoreMap":39},[44,464,465],{"class":46,"line":47},[44,466,379],{},[44,468,469],{"class":46,"line":53},[44,470,471],{},"    u.id,\n",[44,473,474],{"class":46,"line":59},[44,475,476],{},"    u.name,\n",[44,478,479],{"class":46,"line":65},[44,480,481],{},"    COUNT(o.id) AS order_count\n",[44,483,484],{"class":46,"line":71},[44,485,62],{},[44,487,488],{"class":46,"line":77},[44,489,490],{},"LEFT JOIN orders o\n",[44,492,493],{"class":46,"line":212},[44,494,495],{},"    ON u.id = o.user_id\n",[44,497,498],{"class":46,"line":217},[44,499,500],{},"WHERE u.active = true\n",[44,502,503],{"class":46,"line":289},[44,504,505],{},"GROUP BY u.id, u.name;\n",[15,507,508],{},"One query instead of a thousand. The difference is orders of magnitude.",[29,510,512],{"id":511},"missing-indexes","Missing Indexes",[15,514,515],{},"Every column in a WHERE, JOIN, or ORDER BY clause is a candidate for an index. Without indexes, the database scans the entire table.",[34,517,519],{"className":36,"code":518,"language":38,"meta":39,"style":39},"-- This query scans all 5 million rows without an index\nSELECT id, name, email\nFROM users\nWHERE email = 'user@example.com';\n\n-- Add an index\nCREATE INDEX idx_users_email ON users(email);\n",[41,520,521,526,531,536,541,545,550],{"__ignoreMap":39},[44,522,523],{"class":46,"line":47},[44,524,525],{},"-- This query scans all 5 million rows without an index\n",[44,527,528],{"class":46,"line":53},[44,529,530],{},"SELECT id, name, email\n",[44,532,533],{"class":46,"line":59},[44,534,535],{},"FROM users\n",[44,537,538],{"class":46,"line":65},[44,539,540],{},"WHERE email = 'user@example.com';\n",[44,542,543],{"class":46,"line":71},[44,544,197],{"emptyLinePlaceholder":196},[44,546,547],{"class":46,"line":77},[44,548,549],{},"-- Add an index\n",[44,551,552],{"class":46,"line":212},[44,553,554],{},"CREATE INDEX idx_users_email ON users(email);\n",[15,556,557],{},"Indexing rules:",[85,559,560,563,566,569],{},[88,561,562],{},"Index columns used in WHERE clauses with high selectivity",[88,564,565],{},"Index foreign key columns — JOIN performance depends on them",[88,567,568],{},"Composite indexes for multi-column filters — put the most selective column first",[88,570,571],{},"Avoid over-indexing — each index slows writes (INSERT, UPDATE, DELETE)",[29,573,575],{"id":574},"sargability-violations","Sargability Violations",[15,577,578],{},"A \"sargable\" predicate is one where the database can use an index. Wrapping a column in a function makes it non-sargable.",[34,580,582],{"className":36,"code":581,"language":38,"meta":39,"style":39},"-- Non-sargable: function on indexed column\nSELECT *\nFROM orders\nWHERE DATE(created_at) = '2024-01-15';\n\n-- Sargable: range condition on raw column\nSELECT *\nFROM orders\nWHERE created_at >= '2024-01-15'\n    AND created_at \u003C '2024-01-16';\n",[41,583,584,589,593,598,603,607,612,616,620,625],{"__ignoreMap":39},[44,585,586],{"class":46,"line":47},[44,587,588],{},"-- Non-sargable: function on indexed column\n",[44,590,591],{"class":46,"line":53},[44,592,251],{},[44,594,595],{"class":46,"line":59},[44,596,597],{},"FROM orders\n",[44,599,600],{"class":46,"line":65},[44,601,602],{},"WHERE DATE(created_at) = '2024-01-15';\n",[44,604,605],{"class":46,"line":71},[44,606,197],{"emptyLinePlaceholder":196},[44,608,609],{"class":46,"line":77},[44,610,611],{},"-- Sargable: range condition on raw column\n",[44,613,614],{"class":46,"line":212},[44,615,251],{},[44,617,618],{"class":46,"line":217},[44,619,597],{},[44,621,622],{"class":46,"line":289},[44,623,624],{},"WHERE created_at >= '2024-01-15'\n",[44,626,627],{"class":46,"line":295},[44,628,629],{},"    AND created_at \u003C '2024-01-16';\n",[15,631,632],{},"Common non-sargable patterns to avoid:",[634,635,636,649],"table",{},[637,638,639],"thead",{},[640,641,642,646],"tr",{},[643,644,645],"th",{},"Non-Sargable",[643,647,648],{},"Sargable Alternative",[650,651,652,663,675,687],"tbody",{},[640,653,654,660],{},[655,656,657],"td",{},[41,658,659],{},"LOWER(email) = 'test@example.com'",[655,661,662],{},"Use case-insensitive collation",[640,664,665,670],{},[655,666,667],{},[41,668,669],{},"YEAR(created_at) = 2024",[655,671,672],{},[41,673,674],{},"created_at >= '2024-01-01' AND created_at \u003C '2025-01-01'",[640,676,677,682],{},[655,678,679],{},[41,680,681],{},"SUBSTRING(name, 1, 3) = 'ABC'",[655,683,684],{},[41,685,686],{},"name LIKE 'ABC%'",[640,688,689,694],{},[655,690,691],{},[41,692,693],{},"amount \u002F 2 > 50",[655,695,696],{},[41,697,698],{},"amount > 100",[10,700,702],{"id":701},"optimization-case-study","Optimization Case Study",[15,704,705],{},"A reporting query took 45 seconds in production. Here is the original:",[34,707,709],{"className":36,"code":708,"language":38,"meta":39,"style":39},"SELECT c.name, SUM(p.amount) as total\nFROM customers c\nJOIN payments p ON c.id = p.customer_id\nWHERE LOWER(c.country) = 'us'\n    AND YEAR(p.payment_date) = 2024\n    AND p.status != 'failed'\nGROUP BY c.name\nHAVING SUM(p.amount) > 500\nORDER BY total DESC;\n",[41,710,711,716,721,726,731,736,741,746,751],{"__ignoreMap":39},[44,712,713],{"class":46,"line":47},[44,714,715],{},"SELECT c.name, SUM(p.amount) as total\n",[44,717,718],{"class":46,"line":53},[44,719,720],{},"FROM customers c\n",[44,722,723],{"class":46,"line":59},[44,724,725],{},"JOIN payments p ON c.id = p.customer_id\n",[44,727,728],{"class":46,"line":65},[44,729,730],{},"WHERE LOWER(c.country) = 'us'\n",[44,732,733],{"class":46,"line":71},[44,734,735],{},"    AND YEAR(p.payment_date) = 2024\n",[44,737,738],{"class":46,"line":77},[44,739,740],{},"    AND p.status != 'failed'\n",[44,742,743],{"class":46,"line":212},[44,744,745],{},"GROUP BY c.name\n",[44,747,748],{"class":46,"line":217},[44,749,750],{},"HAVING SUM(p.amount) > 500\n",[44,752,753],{"class":46,"line":289},[44,754,755],{},"ORDER BY total DESC;\n",[15,757,758],{},"Problems identified:",[760,761,762,768,774],"ol",{},[88,763,764,767],{},[41,765,766],{},"LOWER(c.country)"," prevents index usage — country values are already consistent",[88,769,770,773],{},[41,771,772],{},"YEAR(p.payment_date)"," prevents index usage — use a range instead",[88,775,776,779],{},[41,777,778],{},"p.status != 'failed'"," has low selectivity — most payments succeed",[15,781,782],{},"Optimized version:",[34,784,786],{"className":36,"code":785,"language":38,"meta":39,"style":39},"SELECT\n    c.name,\n    SUM(p.amount) AS total\nFROM customers c\nJOIN payments p\n    ON c.id = p.customer_id\nWHERE c.country = 'US'\n    AND p.payment_date >= '2024-01-01'\n    AND p.payment_date \u003C '2025-01-01'\n    AND p.status = 'completed'\nGROUP BY c.name\nHAVING SUM(p.amount) > 500\nORDER BY total DESC;\n",[41,787,788,792,796,801,805,810,815,820,825,830,835,839,843],{"__ignoreMap":39},[44,789,790],{"class":46,"line":47},[44,791,379],{},[44,793,794],{"class":46,"line":53},[44,795,394],{},[44,797,798],{"class":46,"line":59},[44,799,800],{},"    SUM(p.amount) AS total\n",[44,802,803],{"class":46,"line":65},[44,804,720],{},[44,806,807],{"class":46,"line":71},[44,808,809],{},"JOIN payments p\n",[44,811,812],{"class":46,"line":77},[44,813,814],{},"    ON c.id = p.customer_id\n",[44,816,817],{"class":46,"line":212},[44,818,819],{},"WHERE c.country = 'US'\n",[44,821,822],{"class":46,"line":217},[44,823,824],{},"    AND p.payment_date >= '2024-01-01'\n",[44,826,827],{"class":46,"line":289},[44,828,829],{},"    AND p.payment_date \u003C '2025-01-01'\n",[44,831,832],{"class":46,"line":295},[44,833,834],{},"    AND p.status = 'completed'\n",[44,836,837],{"class":46,"line":301},[44,838,745],{},[44,840,841],{"class":46,"line":397},[44,842,750],{},[44,844,845],{"class":46,"line":403},[44,846,755],{},[15,848,849],{},"Added indexes:",[34,851,853],{"className":36,"code":852,"language":38,"meta":39,"style":39},"CREATE INDEX idx_payments_date_status\n    ON payments(payment_date, status, customer_id);\n",[41,854,855,860],{"__ignoreMap":39},[44,856,857],{"class":46,"line":47},[44,858,859],{},"CREATE INDEX idx_payments_date_status\n",[44,861,862],{"class":46,"line":53},[44,863,864],{},"    ON payments(payment_date, status, customer_id);\n",[15,866,867],{},"Result: 45 seconds down to 0.3 seconds — a 150x improvement.",[10,869,871],{"id":870},"performance-checklist","Performance Checklist",[85,873,874,880,883,886,889,892],{},[88,875,876,877,879],{},"Replace ",[41,878,314],{}," with explicit column lists",[88,881,882],{},"Eliminate N+1 queries — use JOINs and aggregation instead",[88,884,885],{},"Add indexes on filtered and joined columns",[88,887,888],{},"Make WHERE predicates sargable — avoid functions on indexed columns",[88,890,891],{},"Read the EXPLAIN plan before and after each optimization",[88,893,894],{},"Test with production-like data volumes — small datasets hide slow queries",[10,896,898],{"id":897},"key-takeaways","Key Takeaways",[85,900,901,904,907,912,915],{},[88,902,903],{},"EXPLAIN plans are your primary tool — learn to read them for your database",[88,905,906],{},"Formatting makes performance anti-patterns visible at a glance",[88,908,909,911],{},[41,910,314],{}," and N+1 queries are the two most common causes of slow SQL",[88,913,914],{},"Wrapping indexed columns in functions kills index usage — always write sargable predicates",[88,916,917],{},"One well-placed composite index can cut query time by 100x or more",[10,919,921],{"id":920},"try-it-yourself","Try It Yourself",[15,923,924,925,930],{},"Format and review your queries with our free ",[926,927,929],"a",{"href":928},"\u002Ftools\u002Fsql-formatter","SQL Formatter",". Paste your SQL, check the structure, and spot potential performance issues before they hit production.",[10,932,934],{"id":933},"related-guides","Related Guides",[85,936,937,944],{},[88,938,939,943],{},[926,940,942],{"href":941},"\u002Fguides\u002Fsql-formatting-guide","SQL Formatting Guide: Writing Clean and Readable Queries"," — detailed formatting rules that make optimization easier",[88,945,946,950],{},[926,947,949],{"href":948},"\u002Fguides\u002Fsql-best-practices","SQL Best Practices: Industry Standards for Query Style"," — coding standards for consistent, reviewable SQL",[952,953,954],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":39,"searchDepth":53,"depth":53,"links":956},[957,958,963,964,970,971,972,973,974],{"id":12,"depth":53,"text":13},{"id":23,"depth":53,"text":24,"children":959},[960,961,962],{"id":31,"depth":59,"text":32},{"id":115,"depth":59,"text":116},{"id":175,"depth":59,"text":176},{"id":225,"depth":53,"text":226},{"id":327,"depth":53,"text":328,"children":965},[966,967,968,969],{"id":331,"depth":59,"text":314},{"id":423,"depth":59,"text":424},{"id":511,"depth":59,"text":512},{"id":574,"depth":59,"text":575},{"id":701,"depth":53,"text":702},{"id":870,"depth":53,"text":871},{"id":897,"depth":53,"text":898},{"id":920,"depth":53,"text":921},{"id":933,"depth":53,"text":934},"2026-05-28","Practical techniques to identify and fix slow SQL queries. Learn how to read EXPLAIN plans, avoid common anti-patterns, and write faster SQL.","md",{"immutable":196,"keywords":979},[980,981],"sql-formatter","sql-query-optimization","\u002Fguides\u002Fsql-query-optimization",{"title":5,"description":976},"guides\u002Fsql-query-optimization","UTgybnYOgkEHX1bom1vBNhEZkD3MOKWRmOi2tUmjkVE",1780401328348]