Model Comparison

The same prompt, sent to several models through the FastMetal gateway. Every answer below is the model's real output, with its response time and token count — pick an example, then swap models in the columns.

Optimize a slow database query

Prompt:

The following SQL query runs very slowly on a table with 10 million rows. Please optimize it and explain your changes: SELECT o.order_id, o.order_date, c.customer_name, c.email, SUM(oi.quantity * oi.unit_price) as total_amount FROM orders o JOIN customers c ON c.customer_id = o.customer_id JOIN order_items oi ON oi.order_id = o.order_id WHERE o.order_date BETWEEN '2024-01-01' AND '2024-12-31' AND c.country = 'US' AND o.status != 'cancelled' GROUP BY o.order_id, o.order_date, c.customer_name, c.email HAVING SUM(oi.quantity * oi.unit_price) > 100 ORDER BY total_amount DESC; The table has indexes on orders(order_id) and customers(customer_id) only.

Themainissuesare:-Thereisnoindexon`order_items(order_id)`,sojoiningandaggregatingitemrowscanrequirescanningaverylargetable.-Theexistingindexesdonotsupportthefilterpredicateson`orders.order_date`,`orders.status`,or`customers.country`.-Thequerygroupsbylargetextcolumns(`customer_name`,`email`)eventhoughaggregationonlyneedstohappenattheorderlevel.-`BETWEEN'2024-01-01'AND'2024-12-31'`canexcluderowsonDec31if`order_date`isatimestamp.##RewrittenqueryAggregateorderitemsonlyafternarrowingdowntoqualifyingorders,thenjoincustomerdisplayfieldsafteraggregation.```sqlWITHfiltered_ordersAS(SELECTo.order_id,o.order_date,o.customer_idFROMordersoJOINcustomerscONc.customer_id=o.customer_idWHEREo.order_date>='2024-01-01'ANDo.order_date<'2025-01-01'ANDo.status<>'cancelled'ANDc.country='US'),order_totalsAS(SELECTfo.order_id,fo.order_date,fo.customer_id,SUM(oi.quantity*oi.unit_price)AStotal_amountFROMfiltered_ordersfoJOINorder_itemsoiONoi.order_id=fo.order_idGROUPBYfo.order_id,fo.order_date,fo.customer_idHAVINGSUM(oi.quantity*oi.unit_price)>100)SELECTot.order_id,ot.order_date,c.customer_name,c.email,ot.total_amountFROMorder_totalsotJOINcustomerscONc.customer_id=ot.customer_idORDERBYot.total_amountDESC;```##Whythisisbetter###1.FilterbeforeaggregatingorderitemsTheexpensivepartisusually:```sqlSUM(oi.quantity*oi.unit_price)```TherewrittenqueryfirstidentifiesonlyUS,non-cancelled2024orders.Itthenreadsandsums`order_items`onlyforthoseorders.Withoutanappropriate`order_items(order_id)`index,thedatabasemayscanorhashahugeportionof`order_items`.###2.GrouponlybyIDsandsmallkeycolumnsTheoriginalquerygroupsby:```sqlo.order_id,o.order_date,c.customer_name,c.email```Groupingbynameandemailincreasesgrouping/sortmemoryandCPUusage.Theaggregateisfundamentallyperorder,soaggregatebyorder-relatedkeysfirst,thenretrievecustomerattributesafterward.###3.Useahalf-opendaterangeUse:```sqlo.order_date>='2024-01-01'ANDo.order_date<'2025-01-01'```insteadof:```sqlBETWEEN'2024-01-01'AND'2024-12-31'```If`order_date`containsatimecomponent,`BETWEEN...AND'2024-12-31'`oftenmeansmidnightatthebeginningofDec31,excludingmostofthatday.---#RecommendedindexesThemostimportantmissingindexison`order_items`.```sqlCREATEINDEXidx_order_items_order_idONorder_items(order_id);```Ifyourdatabasesupportscoveringindexes/includedcolumns,use:```sqlCREATEINDEXidx_order_items_order_id_coverONorder_items(order_id)INCLUDE(quantity,unit_price);```ForMySQL/InnoDB,whichdoesnotsupport`INCLUDE`,acoveringalternativeis:```sqlCREATEINDEXidx_order_items_order_id_amountONorder_items(order_id,quantity,unit_price);```Thiscanallowtheaggregationtobeperformedfromtheindexwithoutrepeatedlyreadingtablepages,thoughitmakestheindexlarger.##CustomersindexThequeryfilterscustomersbycountryandthenjoinsby`customer_id`.```sqlCREATEINDEXidx_customers_country_customerONcustomers(country,customer_id);```Ifsupported,includedisplaycolumns:```sqlCREATEINDEXidx_customers_country_customer_coverONcustomers(country,customer_id)INCLUDE(customer_name,email);```ForMySQL:```sqlCREATEINDEXidx_customers_country_customer_coverONcustomers(country,customer_id,customer_name,email);```Becautiousaboutindexinglong`VARCHAR`columnsinMySQL;acoveringindexwithname/emailmaybeunnecessarilylarge.Thesmaller`(country,customer_id)`indexisusuallysufficient.##OrdersindexThebest`orders`indexdependsondatadistribution.IfthequerycommonlystartsfromUScustomers:```sqlCREATEINDEXidx_orders_customer_dateONorders(customer_id,order_date,order_id);```Ifdatefilteringismoreselectivethancountryfiltering:```sqlCREATEINDEXidx_orders_date_customerONorders(order_date,customer_id,order_id);```Becausethispredicateisaninequality:```sqlo.status<>'cancelled'```putting`status`inanormalcompositeindexoftenprovideslimitedbenefit.MostdatabasescannotefficientlyuseaB-treeindexfor“everythingexceptonevalue,”particularlyifmostordersarenon-cancelledanyway.Ifyourdatabasesupportspartial/filteredindexes,thisisideal:```sqlCREATEINDEXidx_orders_active_date_customerONorders(order_date,customer_id,order_id)WHEREstatus<>'cancelled';```ForPostgreSQLorSQLServer,thiscanbesignificantlybetterthanindexing`status`normally.---#PracticalindexsetAstronggeneralstartingpointwouldbe:```sqlCREATEINDEXidx_order_items_order_idONorder_items(order_id);CREATEINDEXidx_customers_country_customerONcustomers(country,customer_id);CREATEINDEXidx_orders_date_customerONorders(order_date,customer_id,order_id);```IfUScustomersareasmallsubsetandtheoptimizerdrivesfrom`customers`,preferthisordersindexinstead:```sqlCREATEINDEXidx_orders_customer_dateONorders(customer_id,order_date,order_id);```Donotcreatebothordersindexeswithoutvalidatingwith`EXPLAIN`,becausetheycanconsumesubstantialstorageandslowinserts/updates.---#VerifywiththeexecutionplanRunthedatabase-specificequivalentof:```sqlEXPLAINANALYZEWITHfiltered_ordersAS(...)SELECT...```Lookfor:-Anindexseek/rangescanon`orders`forthedaterange.-Anindexlookuporscanon`customers(country,customer_id)`.-Indexedlookupsinto`order_items`by`order_id`.-Nofullscanofall`order_items`rowsunlessthedate/countryfilterslegitimatelymatchalargepercentageoforders.-Reducedrowsenteringtheaggregationstage.Thesinglebiggestlikelyimprovementisadding:```sqlCREATEINDEXidx_order_items_order_idONorder_items(order_id);```becausetheaggregationjoincannotscalewellwithoutefficientlylocatingitemsforeachqualifyingorder.

Response time:22141ms
Words:824
Tokens:1993

TooptimizethegivenSQLquery,weneedtoaddressseveralissues,includingthenumberoftablesjoined,thegroupbycondition,thewhereclause,andtheindexusage.Here'sabreakdownofthestepsandtheresultingoptimizedquery:###IssuestoAddress:1.**IndexUsage**:Thecurrentindexsetupison`orders(order_id)`and`customers(customer_id)`,whichhelps,butcolumns`o.order_date`,`c.customer_name`,and`c.email`arenotusedforkeepingindexes.However,`order_date`isnarrowenoughthatmovingittoafilterearlierinthequeryexecutionmayhelp.2.**_FILTERING**:Addingaconditionforfilteringthetableasearlyaspossibleiscrucial,suchasbeforetheJOINoperation.3.**AGGREGATEFUNCTIONS**:The`SUM`intheWHEREclausemightbetricky,butitcanstillbemovedforoptimization,thoughitmaybesimplertorecastthequery.4.**PROJECTEDCOLUMNS**:Checkiftotalamountsarecalculatedtwice.###ProposedSolution:1.**UseanIndexon`order_date`**:Ensureyouhaveanindexon`order_date`ifpossibleormovefilteringaftertablejointoreducethesizeofdatabeingprocessed.2.**AvoidUsing`GROUPBY`ClauseforOrdering**:UseanwindowfunctionoraddSORTEDindexifpossible.Let'sproceedbymakingnecessaryadjustments:```sql--OptimizedQuerySELECTo.order_id,o.order_date,c.customer_name,c.email,SUM(oi.quantity*oi.unit_price)astotal_amountFROM(SELECTo.order_id,o.order_date,c.customer_name,c.email,SUM(oi.quantity*oi.unit_price)ASsub_totalFROMordersoJOINcustomerscONc.customer_id=o.customer_idJOINorder_itemsoiONoi.order_id=o.order_idWHEREo.order_dateBETWEEN'2024-01-01'AND'2024-12-31'ANDc.country='US'ANDo.status!='cancelled'GROUPBYo.order_id,o.order_date,c.customer_name,c.email)ASresultWHEREtotal_amount>100ORDERBYtotal_amountDESC;```Intheabovequery:-**NestedSELECT**:Asubqueryiscreatedto`SUM(oi.quantity*oi.unit_price)`thequalifiedrows.-**ResultTable**:Onlyqualifyingrowswith`total_amount>100`aretakenforward.-**NoGROUPBYinFinalQuerybutusedwithinSelect**:Initial`GROUPBY`ensuresthattheGROUPrequirementsaremet.###Explanation:1.**Subquery**:Aggregatesnecessarydata.2.**ResultTable**:Holdsthenecessarycleanedandfiltereddata.3.**FinalSELECT**:Orderstheresultsetbasedonrelevantvalue-`total_amount`.Ensurethattheadditionalindexesonrelatedcolumnsifpossible:```sql--IndexOn`order_date`CREATEINDEXindex_order_dateONorders(order_date);--IndexOnSubtotalCREATEINDEXindex_sub_totalONresult(total_amount);```###Optimizations:-**Pre-filtering**:TheWHEREclausesensuringearlierfilteringreducesthesizeoftheresultsetbeforeanygrouping.-**NarrowViews**:Usingintermediateselectionstolimitthescopeofwhatneedstogroupandsomewhatflattenthequerybeforeordering.Thisstrategyavoidsusing`GROUPBY`forthequerystructureandensuresfetchingnecessaryrows.Optimizesforbothspeedandmemoryusage.

Response time:3112ms
Words:457
Tokens:750

#SQLQueryOptimization##AnalysisofPerformanceBottlenecksThequerysuffersfromseveralissuesatscale:1.**Missingindexes**onfiltered/joinedcolumnsfulltablescans2.**Joiningbeforefiltering**unnecessarilylargeintermediateresultsets3.**Nocoveringindexes**excessiverandomI/Ofromrowlookups4.**`!='cancelled'`predicate**poorindexselectivitywithoutrestructuring---##Step1:AddStrategicIndexes```sql--Indexonorders:coverstheWHEREfiltersandJOINtocustomers--Compositeindexwithmostselective/filterablecolumnsfirstCREATEINDEXidx_orders_date_status_customerONorders(order_date,status,customer_id)INCLUDE(order_id);--covering:avoidsheaplookup--Indexoncustomers:coverscountryfilter+joinCREATEINDEXidx_customers_countryONcustomers(country,customer_id)INCLUDE(customer_name,email);--coveringindex--Indexonorder_items:coversjoin+aggregationcolumnsCREATEINDEXidx_order_items_order_idONorder_items(order_id)INCLUDE(quantity,unit_price);--coveringindex```>**WhyINCLUDEcolumns?**Theyexistonlyattheleafleveloftheindex,makingita*coveringindex*theengineneverneedstogobacktothetableheap.---##Step2:RestructuretheQuery```sql--OptimizedqueryusingCTEstofilterearlyandreducejoinsizesWITHfiltered_ordersAS(SELECTorder_id,order_date,customer_idFROMordersWHEREorder_dateBETWEEN'2024-01-01'AND'2024-12-31'ANDstatus!='cancelled'),us_customersAS(SELECTcustomer_id,customer_name,emailFROMcustomersWHEREcountry='US'),order_totalsAS(SELECToi.order_id,SUM(oi.quantity*oi.unit_price)AStotal_amountFROMorder_itemsoiINNERJOINfiltered_ordersfoONfo.order_id=oi.order_idGROUPBYoi.order_idHAVINGSUM(oi.quantity*oi.unit_price)>100)SELECTfo.order_id,fo.order_date,uc.customer_name,uc.email,ot.total_amountFROMorder_totalsotJOINfiltered_ordersfoONfo.order_id=ot.order_idJOINus_customersucONuc.customer_id=fo.customer_idORDERBYot.total_amountDESC;```---##WhyEachChangeHelps```┌─────────────────────────────────────────────────────────────────────┐OPTIMIZATIONBREAKDOWN├──────────────────┬──────────────────────────────────────────────────┤ProblemSolution&Impact├──────────────────┼──────────────────────────────────────────────────┤FulltablescanCompositeindexesonWHEREclausecolumnsonordersIndexrangescanondate,thenfilterstatusReduces10Mrowsto~relevantdaterange├──────────────────┼──────────────────────────────────────────────────┤FulltablescanIndexoncustomers(country)withINCLUDEoncustomersSeeksdirectlyto'US'customersCoveringindexavoidstablelookup├──────────────────┼──────────────────────────────────────────────────┤ExpensiveJOINorder_itemsindexon(order_id)withINCLUDEonorder_itemsIndex-onlyscanforaggregation├──────────────────┼──────────────────────────────────────────────────┤LatefilteringCTEstructurefiltersBEFOREjoining(joinexplosion)Aggregateorder_itemsfirst,THENjoinHAVINGeliminatesrowsbeforecustomerjoin├──────────────────┼──────────────────────────────────────────────────┤GROUPBYonGrouponlybyorder_idinorder_totals4columnsSmallergroupingset,joindetailsafterLessmemoryforhash/sortaggregation├──────────────────┼──────────────────────────────────────────────────┤SortinglargeORDERBYhappensonthefinalsmallresultsetresultsetOnlyrowssurvivingHAVING>100aresorted└──────────────────┴──────────────────────────────────────────────────┘```---##AdditionalConsiderations###If`status`hasfewdistinctvalues,considerrewritingthe`!=`:```sql--Moreindex-friendly:explicitlylistwantedstatusesANDstatusIN('pending','shipped','delivered','processing')--The!=operatorcanpreventefficientindexrangescans```###Ifthisrunsrepeatedly,consideramaterializedview:```sql--FordashboardsorrepeatedreportingqueriesCREATEMATERIALIZEDVIEWmv_us_order_summariesASSELECTo.order_id,o.order_date,o.customer_id,SUM(oi.quantity*oi.unit_price)AStotal_amountFROMordersoJOINorder_itemsoiONoi.order_id=o.order_idWHEREo.status!='cancelled'GROUPBYo.order_id,o.order_date,o.customer_id;--RefreshonascheduleREFRESHMATERIALIZEDVIEWmv_us_order_summaries;```###VerifywithEXPLAINANALYZE:```sqlEXPLAINANALYZE<your_query>;--Lookfor:SeqScanshouldbecomeIndexScan/IndexOnlyScan--Lookfor:accuraterowestimates(avoidplanmisestimates)--Lookfor:nestedloopsonsmallsets,hashjoinsonlargerones```The**biggestwins**comefromthecoveringindexes(eliminatingheaplookupsonallthreetables)and**aggregatingbeforejoining**customerdetails(dramaticallyreducingthenumberofrowsflowingthroughthejoinpipeline).

Response time:28403ms
Words:675
Tokens:1582

Answers to "SQL Query Optimization"

47 models answered this prompt. Full text and timings are in the viewer above.

gpt-5.6-terra

The main issues are: - There is no index on `order_items(order_id)`, so joining and aggregating item rows can require scanning a very large table. - The existing indexes do not support the filter predicates on `orders.order_date`, `orders.status`, or `customers.country`. - The query groups by large text columns (`customer_name`, `email`) even though aggregation only needs to happen at the order level. - `BETWEEN '2024-01-01' AND '2024-12-31'` can exclude rows on Dec 31 if `order_date` is a timestamp. ## Rewritten query Aggregate order items only after narrowing down to qualifying orders, then join customer display fields after aggregation. ```sql WITH filtered_orders AS ( SELECT o.order_id,…

Response time: 22141ms · Tokens: 1993

mistral-voxtral-mini-3b-2507

To optimize the given SQL query, we need to address several issues, including the number of tables joined, the group by condition, the where clause, and the index usage. Here's a breakdown of the steps and the resulting optimized query: ### Issues to Address: 1. **Index Usage**: The current index setup is on `orders(order_id)` and `customers(customer_id)`, which helps, but columns `o.order_date`, `c.customer_name`, and `c.email` are not used for keeping indexes. However, `order_date` is narrow enough that moving it to a filter earlier in the query execution may help. 2. **_FILTERING**: Adding a condition for filtering the table as early as possible is crucial, such as before the JOIN operati…

Response time: 3112ms · Tokens: 750

anthropic-claude-opus-4-6

# SQL Query Optimization ## Analysis of Performance Bottlenecks The query suffers from several issues at scale: 1. **Missing indexes** on filtered/joined columns → full table scans 2. **Joining before filtering** → unnecessarily large intermediate result sets 3. **No covering indexes** → excessive random I/O from row lookups 4. **`!= 'cancelled'` predicate** → poor index selectivity without restructuring --- ## Step 1: Add Strategic Indexes ```sql -- Index on orders: covers the WHERE filters and JOIN to customers -- Composite index with most selective/filterable columns first CREATE INDEX idx_orders_date_status_customer ON orders(order_date, status, customer_id) INCLUDE (order_id); -- coveri…

Response time: 28403ms · Tokens: 1582

anthropic-claude-sonnet-4-6

## Query Optimization Analysis ### Recommended Indexes ```sql -- Most critical: composite index for the heavy filtering on orders CREATE INDEX idx_orders_date_status ON orders(order_date, status, customer_id); -- Filter on customers before joining CREATE INDEX idx_customers_country ON customers(country, customer_id, customer_name, email); -- Support the JOIN and aggregation on order_items CREATE INDEX idx_order_items_order_id ON order_items(order_id, quantity, unit_price); ``` **Why these indexes:** - `idx_orders_date_status` — the WHERE clause filters on `order_date` and `status`. Without this, every row in a 10M-row table gets scanned. Leading with `order_date` supports the BETWEEN range s…

Response time: 17854ms · Tokens: 1135

anthropic-claude-haiku-4-5

# SQL Query Optimization Here's the optimized query with explanations: ```sql SELECT o.order_id, o.order_date, c.customer_name, c.email, SUM(oi.quantity * oi.unit_price) as total_amount FROM orders o INNER JOIN customers c ON c.customer_id = o.customer_id INNER JOIN order_items oi ON oi.order_id = o.order_id WHERE o.order_date BETWEEN '2024-01-01' AND '2024-12-31' AND c.country = 'US' AND o.status != 'cancelled' GROUP BY o.order_id, o.order_date, c.customer_name, c.email HAVING SUM(oi.quantity * oi.unit_price) > 100 ORDER BY total_amount DESC; ``` ## Required Index Additions ```sql -- CRITICAL: Add composite indexes CREATE INDEX idx_orders_date_status ON orders(order_date, status, customer_i…

Response time: 6596ms · Tokens: 944

minimax-m2.7

# SQL Query Optimization Analysis ## Current Performance Issues ### 1. **Missing Indexes (Primary Problem)** The existing indexes on primary keys are insufficient. The query filters and joins on columns that lack indexes: | Column | Used For | Index Needed | |--------|----------|--------------| | `orders.order_date` | Range filter (BETWEEN) | ✅ Critical | | `orders.customer_id` | JOIN condition | ✅ Critical | | `orders.status` | WHERE filter | Recommended | | `customers.country` | WHERE filter | Recommended | | `order_items.order_id` | JOIN condition | ✅ Critical | ### 2. **Redundant Calculation** `SUM(oi.quantity * oi.unit_price)` is calculated twice—once in SELECT and again in HAVING. ###…

Response time: 31381ms · Tokens: 1445

glm-5

The primary reason for the slow performance is the lack of indexes to support the filtering and joining operations, combined with an inefficient query structure that processes large string columns (`customer_name`, `email`) during the heavy aggregation phase. Here is the optimized solution, broken down into the optimized query and the necessary index changes. ### 1. Optimized SQL Query We will restructure the query to aggregate the line items *before* joining to the customer table. This reduces the memory usage and CPU required for the `GROUP BY` operation, as it avoids carrying customer strings through the aggregation process. ```sql SELECT o.order_id, o.order_date, c.customer_name, c.email…

Response time: 58867ms · Tokens: 5541

llm-jp-3.1-8x13b-instruct4

To optimize the given query, we can take the following steps: 1. Add an index on the order_items table on the order_id and unit_price columns. 2. Use a covering index on the orders table to include the order_date, status, and customer_id columns in the index. 3. Rewrite the query to use the new index and remove the redundant columns from the SELECT clause. 4. Use the index hint to ensure that the optimizer uses the covering index. Here's the optimized query: CREATE INDEX idx_order_items_order_id_unit_price ON order_items (order_id, unit_price); CREATE INDEX idx_orders_order_date_status_customer_id ON orders (order_date, status, customer_id); SELECT o.order_id, o.order_date, c.customer_name,…

Response time: 5488ms · Tokens: 595

gpt-oss-120b

## TL;DR – What you should do | What you need | Why it helps | How to implement | |---------------|--------------|------------------| | **Composite index on `orders`** covering the predicates (`order_date`, `status`, `customer_id`) and the join column (`order_id`). | Filters the 10 M rows *before* the join, so the planner can discard most rows early and use an **index‑only scan** for the `order_id` that is needed for the join. | ```sql CREATE INDEX ix_orders_date_status_cust ON orders(order_date, status, customer_id) INCLUDE (order_id); ``` | | **Composite index on `customers`** covering the predicate (`country`) and the join column (`customer_id`). | Lets the engine find the US customers *f…

Response time: 14067ms · Tokens: 3205

anthropic-claude-fable-5

# Optimized Query & Explanation ## The Core Problems 1. **No index on `order_items(order_id)`** — the biggest issue. Joining 10M orders to order_items forces full scans or hash joins over the entire items table. 2. **No index supporting the date-range filter** on `orders.order_date`. 3. **No index on `customers.country`**. 4. **Grouping happens after joining wide customer columns**, inflating the rows carried through aggregation. 5. **`status != 'cancelled'`** is not index-friendly (inequality), but it's usually low-selectivity anyway. ## Step 1: Add the Missing Indexes ```sql -- Critical: supports the join and lets aggregation use an index-only scan CREATE INDEX idx_order_items_order_id ON…

Response time: 42356ms · Tokens: 1569

anthropic-claude-opus-4-8

# Query Optimization Analysis ## Root Causes of Slow Performance 1. **No index on `orders.order_date`** — the date range filter scans all 10M rows. 2. **No index on `orders.customer_id`** — the join to customers is inefficient. 3. **No index on `order_items.order_id`** — the join aggregates via full scans. 4. **No index on `customers.country`** — the US filter isn't index-assisted. 5. **`SELECT DISTINCT`-style GROUP BY** on many columns is expensive. The existing indexes (`orders(order_id)`, `customers(customer_id)`) are primary-key-style indexes that don't help *any* of the filter/join predicates here. --- ## Step 1: Add the Right Indexes ```sql -- Supports the date-range + status filter an…

Response time: 22464ms · Tokens: 1667

anthropic-claude-opus-5

## Diagnosis: why it's slow Four separate problems, in rough order of impact: 1. **`order_items` has no index on `order_id`.** This is the killer. Every join strategy is bad: the planner either scans the entire `order_items` table (which is *larger* than `orders` — likely 30–50M rows) to build a hash table, or does a full scan per order. Everything else is secondary to this. 2. **No index supports the `orders` predicate.** `order_date BETWEEN … AND status != 'cancelled'` forces a full scan of 10M rows. 3. **No index on `customers(country)`,** and no index on `orders(customer_id)` for the join direction the planner may prefer. 4. **The `GROUP BY` is doing unnecessary work.** You're grouping b…

Response time: 62202ms · Tokens: 4980

anthropic-claude-sonnet-5

# Query Optimization Analysis ## Problems Identified 1. **Missing indexes** on filter/join columns (`order_date`, `status`, `country`, `customer_id` FK, `order_id` FK) 2. **`!=` operator** on `status` prevents efficient index usage (can't use range scan) 3. **No pre-aggregation** — joining `order_items` before grouping means the optimizer scans all matching item rows, multiplying row counts before filtering 4. **Full table scan risk** on 10M rows with no way to narrow down early 5. **HAVING computes SUM twice implicitly** — no functional issue, but worth noting for readability ## Optimized Query ```sql -- Step 1: Pre-aggregate order_items to avoid row explosion WITH order_totals AS ( SELECT…

Response time: 19475ms · Tokens: 1574

deepseek-v4-flash

The query is slow due to missing indexes on filter and join columns, causing full table scans on large tables (10M rows). The current indexes only cover primary keys, which are insufficient for the `WHERE`, `JOIN`, and `GROUP BY` operations. ### Identified Issues 1. **No index on `orders.order_date` and `orders.status`** – The `WHERE` clause filters by `order_date` and `status`, but neither column has an index. 2. **No index on `customers.country`** – Filtering `c.country = 'US'` forces a full scan of `customers`. 3. **No index on `order_items.order_id`** – The join `oi.order_id = o.order_id` is not supported by an index, causing a full scan of `order_items` for each order. 4. **Expensive `H…

Response time: 17213ms · Tokens: 1449

glm-5.3

## Why it's slow With only primary-key indexes, the database has no efficient path to any of the filters or joins: 1. **`orders.order_date` has no index** → the date filter forces a full scan of all 10M rows. 2. **`order_items.order_id` has no index** → this is usually the dominant cost. `order_items` is typically the *largest* table (several rows per order), and the join either full-scans it or probes it repeatedly. 3. **`customers.country` has no index** → the country filter also requires a scan (less critical since `customers` is small, but it limits the optimizer's join-order options). ## Step 1: Add the right indexes (this is 95% of the fix) ```sql -- Date range becomes an index range s…

Response time: 80586ms · Tokens: 6106

deepseek-v4-pro

The query itself is logically sound, but it is slow because none of the columns used in filtering, joining, or aggregating have appropriate indexes. The existing indexes only cover `orders(order_id)` and `customers(customer_id)`, forcing full table scans on at least one of the large tables. **Optimized Query** No rewrites are needed – the same SQL will benefit tremendously from the following indexes: ```sql SELECT o.order_id, o.order_date, c.customer_name, c.email, SUM(oi.quantity * oi.unit_price) AS total_amount FROM orders o JOIN customers c ON c.customer_id = o.customer_id JOIN order_items oi ON oi.order_id = o.order_id WHERE o.order_date BETWEEN '2024-01-01' AND '2024-12-31' AND c.countr…

Response time: 83517ms · Tokens: 4229

gemini-3.5-flash

To optimize this query for a 10-million-row database, we need to address two major bottlenecks: **missing indexes** (the primary cause of the slowness) and **expensive grouping operations on string columns** (`customer_name`, `email`). Here is the optimized solution, divided into database index changes and SQL query rewrites. --- ### Step 1: Add the Critical Indexes (The most important step) Without these indexes, the database is forced to perform full-table scans on millions of rows. Run the following DDL statements: ```sql -- 1. Index for the order_items join and aggregation (Covering Index) CREATE INDEX idx_order_items_id_price ON order_items (order_id, quantity, unit_price); -- 2. Index…

Response time: 34340ms · Tokens: 5277

gemini-flash-lite-free

To optimize this query for a 10-million-row dataset, we need to address two main performance bottlenecks: **lack of proper indexing** and **unnecessary data processing** (joining and scanning rows before filtering). Here is the optimized SQL query, followed by the required indexes and a detailed explanation of the changes. ### The Optimized Query ```sql SELECT o.order_id, o.order_date, c.customer_name, c.email, SUM(oi.quantity * oi.unit_price) AS total_amount FROM customers c JOIN orders o ON c.customer_id = o.customer_id JOIN order_items oi ON o.order_id = oi.order_id WHERE c.country = 'US' -- Filter selective table first AND o.order_date >= '2024-01-01' -- SARGABLE date range AND o.order_d…

Response time: 4116ms · Tokens: 1014

glm-4.7

The primary reason this query is slow is that it requires the database to scan millions of rows to find the specific records matching your `WHERE` and `JOIN` conditions. With the current indexes (only Primary Keys), the database cannot quickly locate orders by date, status, or country. You do not need to rewrite the SQL query logic; instead, you need to add **Composite Indexes** to support the filtering, joining, and aggregation operations. Here are the optimizations: ### 1. Create Indexes Run the following SQL commands to create the necessary indexes: ```sql -- 1. Index for filtering Orders efficiently CREATE INDEX idx_orders_date_status_cust ON orders (order_date, status, customer_id); --…

Response time: 101651ms · Tokens: 4017

mimo-v2.5

## Analysis of Current Query The query has three main performance issues: 1. **Missing indexes on filtered/joined columns** 2. **Full table scans on large tables** 3. **Inefficient join order and aggregation** ## Optimized Query ```sql -- 1. First, create the necessary indexes (in order of priority) CREATE INDEX idx_orders_date_status ON orders(order_date, status, customer_id); CREATE INDEX idx_customers_country ON customers(country, customer_id, customer_name, email); CREATE INDEX idx_order_items_composite ON order_items(order_id, quantity, unit_price); -- 2. Optimized query with rewrite WITH filtered_orders AS ( SELECT order_id, order_date, customer_id FROM orders WHERE order_date BETWEEN…

Response time: 79933ms · Tokens: 6679

glm-4.7-flash

The primary reason this query runs slowly is that it lacks **indexes** on the filtering and joining columns. Specifically, the `order_items` table is performing full table scans, and the `orders` table is scanning every row to find the dates. Here is the optimized solution. ### 1. Optimized SQL Query The logic of your query is correct. The optimization comes from adding the necessary indexes, which allows the database to find specific rows instantly rather than looking at every single one. ```sql SELECT o.order_id, o.order_date, c.customer_name, c.email, SUM(oi.quantity * oi.unit_price) as total_amount FROM orders o JOIN customers c ON c.customer_id = o.customer_id JOIN order_items oi ON oi.…

Response time: 89275ms · Tokens: 3073

glm-5.1

To optimize this query, we need to address two major areas: **Missing Indexes** and **Query Structure**. Currently, the database is likely performing full table scans on all three tables, joining millions of rows, and then filtering and grouping them at the very end. This causes massive memory usage and CPU spikes. Here is the optimized query, followed by the necessary indexes and a detailed explanation. ### Optimized Query ```sql WITH ValidOrderTotals AS ( SELECT o.order_id, o.order_date, o.customer_id, SUM(oi.quantity * oi.unit_price) AS total_amount FROM orders o JOIN order_items oi ON o.order_id = oi.order_id WHERE o.order_date >= '2024-01-01' AND o.order_date < '2025-01-01' AND o.status…

Response time: 71015ms · Tokens: 3194

glm-5.2

To optimize this query on a table with 10 million rows, we need to address two main issues: **missing indexes** and **inefficient query structure** (specifically, grouping by unnecessary string columns and using a non-optimal date filter). ### 1. Add Missing Indexes The current schema only has indexes on primary keys (`orders.order_id` and `customers.customer_id`). When joining large tables and filtering on specific columns, you need composite indexes to avoid full table scans. Run the following to add the necessary indexes: ```sql -- Index for joining order_items efficiently CREATE INDEX idx_order_items_order_id ON order_items(order_id); -- Index for filtering orders by date and status, and…

Response time: 21707ms · Tokens: 3011

gpt-5.6-sol

The main bottlenecks are likely: - No index on `order_items(order_id)`. - No useful index for the date/status/customer filtering on `orders`. - No index for `customers.country`. - Grouping by wide text columns (`customer_name`, `email`). - `BETWEEN '2024-01-01' AND '2024-12-31'` can omit most of December 31 if `order_date` is a timestamp. ### Rewritten query ```sql WITH order_totals AS ( SELECT o.order_id, o.order_date, o.customer_id, SUM(oi.quantity * oi.unit_price) AS total_amount FROM orders o JOIN customers fc ON fc.customer_id = o.customer_id AND fc.country = 'US' JOIN order_items oi ON oi.order_id = o.order_id WHERE o.order_date >= '2024-01-01' AND o.order_date < '2025-01-01' AND o.sta…

Response time: 41884ms · Tokens: 1970

grok-4.5

## Optimized Query and Indexing ### Recommended indexes Add these (adjust names/types to your DB): ```sql -- Orders: support date range + status filter, cover join keys CREATE INDEX idx_orders_date_status_cust ON orders (order_date, status, customer_id) INCLUDE (order_id); -- or just add order_id to the key if INCLUDE isn't supported -- Better variant if status is selective / low cardinality: CREATE INDEX idx_orders_date_cust ON orders (order_date, customer_id) INCLUDE (order_id, status); -- Customers: filter by country, cover name/email CREATE INDEX idx_customers_country ON customers (country) INCLUDE (customer_id, customer_name, email); -- Order items: join + aggregation CREATE INDEX idx_o…

Response time: 30819ms · Tokens: 1571

inkling

The query is slow because it forces full table scans and hash-joins across all three large tables. With 10 M rows, every missing filter/join column becomes catastrophic. Key problems: 1. **No index on `order_items(order_id)`** – the DB must scan all items (potentially 50 M+ rows) to match each order. 2. **No useful filter index on `orders`** – the date range and status filter scan the full 10 M row table. 3. **No filter index on `customers`** – every US customer lookup scans the whole customer table. 4. **`BETWEEN ... '2024-12-31'`** is dangerous if `order_date` is a `DATETIME`/`TIMESTAMP`; it cuts off the last day after midnight. 5. The aggregation and `ORDER BY total_amount DESC` happen on…

Response time: 44731ms · Tokens: 8075

kimi-k2.6

Here is the optimized query, followed by the indexes you need and a detailed explanation of why this is faster. ## Optimized Query ```sql WITH order_totals AS ( SELECT order_id, SUM(quantity * unit_price) AS total_amount FROM order_items GROUP BY order_id HAVING SUM(quantity * unit_price) > 100 ) SELECT o.order_id, o.order_date, c.customer_name, c.email, ot.total_amount FROM orders o JOIN customers c ON c.customer_id = o.customer_id JOIN order_totals ot ON ot.order_id = o.order_id WHERE o.order_date BETWEEN '2024-01-01' AND '2024-12-31' AND c.country = 'US' AND o.status != 'cancelled' ORDER BY ot.total_amount DESC; ``` ## Indexes to Create ```sql -- 1. Orders: covers the date range filter, s…

Response time: 103119ms · Tokens: 9503

mimo-v2.5-pro

# SQL Query Optimization ## Diagnosing the Problem ``` EXPLAIN ANALYZE -- (original query) ``` The original query has **multiple compounding performance problems**: ``` Slow Path (original): ┌──────────────────────────────────────────────────────┐ │ 1. Full table scan on `orders` (10M rows) │ │ → No index on order_date or status │ │ 2. Full table scan on `customers` │ │ → No index on country │ │ 3. Full table scan on `order_items` │ │ → No index on order_id (FK!) │ │ 4. Massive intermediate result set joined in memory │ │ 5. GROUP BY on 4 columns across 3 tables │ │ 6. Sort entire result set for ORDER BY │ └──────────────────────────────────────────────────────┘ ``` --- ## Step 1: Add Strate…

Response time: 40828ms · Tokens: 2210

minimax-m3

# SQL Query Optimization Analysis ## 🔍 Diagnosis: Why the Query is Slow Working through the query logic against a 10M-row `orders` table (with presumably tens of millions of `order_items` rows), I count **at least 6 major bottlenecks**: | # | Problem | Impact | |---|---------|--------| | 1 | **No index on `orders.order_date`** — the range filter forces a full sequential scan of 10M rows | Huge | | 2 | **No index on `customers.country`** — country filter scans all customers | High | | 3 | **`SUM(oi.quantity * oi.unit_price)` is computed twice** (in `SELECT` and `HAVING`) | Medium | | 4 | **GROUP BY includes wide text columns** (`customer_name`, `email`) after JOIN, before aggregation pushdow…

Response time: 22187ms · Tokens: 2733

muse-glimmer-30b

The query is slow because it has to scan the whole `orders` and `order_items` tables and join them before it can filter. You only have indexes on `orders(order_id)` and `customers(customer_id)`. That means the `WHERE` on `order_date`, `status` and `customers.country` is a full table scan, and the join to `order_items` is a full scan + hash aggregate on 10M rows. ### 1. Indexing to make the filters sargable ```sql -- Orders: filter first by date then status, then join to customers CREATE INDEX idx_orders_date_status_customer ON orders(order_date, status, customer_id); -- Customers: filter by country, then join CREATE INDEX idx_customers_country_id ON customers(country, customer_id) INCLUDE (c…

Response time: 28968ms · Tokens: 2383

qwen3.6-27b

Here’s a production-ready optimization strategy. **90% of the performance gain will come from adding the right indexes**, while the query restructuring ensures the optimizer leverages them efficiently. ### 🔑 1. Required Indexes Run these first. They eliminate full table scans and enable index-only operations: ```sql -- 1. Filter US customers quickly & avoid table lookups for customer_id CREATE INDEX idx_customers_country_id ON customers(country, customer_id); -- 2. Support the join from customers, then filter by date & status -- Column order: join key first, then range/filter columns, then PK CREATE INDEX idx_orders_cust_date_status_id ON orders(customer_id, order_date, status, order_id); -…

Response time: 99585ms · Tokens: 5599

kimi-k3

## Why it's slow With only `orders(order_id)` and `customers(customer_id)` indexed, the database has no efficient access path for anything in this query: 1. **`order_items.order_id` has no index** — this is the biggest problem. The join to `order_items` (likely the largest table) forces either a full scan of `order_items` *per order* or a massive hash join. 2. **`orders.order_date` has no index** — the date filter requires a full scan of all 10M orders. 3. **`customers.country` has no index** — full scan of customers. 4. **Wide GROUP BY key** — grouping by 4 columns (including strings) makes the sort/temp table bigger than necessary. 5. **`BETWEEN '2024-01-01' AND '2024-12-31'`** — if `order…

Response time: 96610ms · Tokens: 5014

qwen3.7-max

# SQL Query Optimization ## 🔴 The Root Cause: Missing Indexes Your query is doing **full table scans** on every join and filter because the only indexes are on primary keys. The most catastrophic missing index is on `order_items(order_id)` — every single order requires a full scan of the `order_items` table. --- ## Step 1: Add Critical Indexes (Biggest Impact) ```sql -- 🔴 CRITICAL: Without this, joining order_items is a full table scan -- for EVERY row from orders. With 10M rows, this alone could take minutes. CREATE INDEX idx_order_items_order_id ON order_items(order_id, quantity, unit_price); -- Filters orders by date range + status, and covers the join to customers CREATE INDEX idx_orde…

Response time: 56938ms · Tokens: 2986

random-free

Below is a practical “road‑map” you can follow to turn that 10 M‑row query from **minutes** into **seconds** (or even sub‑second if the engine supports it). I’ll walk through the *why* of each change, show the exact index definitions you need, and give a rewritten version of the query that respects the new schema. --- ## 1️⃣ What the original plan is doing (and why it’s slow) | Step | What the optimizer sees | Costly behaviour | |------|--------------------------|-----------------| | `orders` → `order_items` → `customers` | 3 separate hash/hash joins (or nested‑loop) | No join predicate that can use the existing single‑column indexes efficiently. | | `WHERE o.order_date BETWEEN … AND … AND c…

Response time: 71497ms · Tokens: 3711

gpt-5.6-luna

A good approach is to filter the orders and customers first, then aggregate only the order items belonging to those orders. ```sql WITH eligible_orders AS ( SELECT o.order_id, o.order_date, c.customer_name, c.email FROM orders AS o JOIN customers AS c ON c.customer_id = o.customer_id WHERE o.order_date >= DATE '2024-01-01' AND o.order_date < DATE '2025-01-01' AND o.status <> 'cancelled' AND c.country = 'US' ), item_totals AS ( SELECT oi.order_id, SUM(oi.quantity * oi.unit_price) AS total_amount FROM order_items AS oi JOIN eligible_orders AS eo ON eo.order_id = oi.order_id GROUP BY oi.order_id ) SELECT eo.order_id, eo.order_date, eo.customer_name, eo.email, it.total_amount FROM eligible_order…

Response time: 21386ms · Tokens: 1989

grok-4.6

The query is slow mainly because it filters and joins on columns that are not indexed, expands every matching order to all of its line items before aggregating, and uses predicates that are harder for the optimizer to seek on. With only PK-style indexes on `orders(order_id)` and `customers(customer_id)`, the engine is almost certainly scanning most of `orders` and `order_items`. ## Recommended indexes ```sql -- Orders: support the date range, then filter status, then join CREATE INDEX idx_orders_date_status_cust ON orders (order_date, status, customer_id) INCLUDE (order_id); -- covering; omit INCLUDE on MySQL 5.7 / use a composite instead -- Customers: equality on country, then join key CREA…

Response time: 44205ms · Tokens: 2761

gemini-3.7-flash

To fix the performance issues on a 10-million-row dataset, optimizations are needed at both the **indexing level** (to eliminate full table scans) and the **query structure level** (to minimize memory overhead during grouping). --- ### Step 1: Add Essential Indexes Without proper indexes, the database must scan all 10M rows for every table. Create the following composite indexes: ```sql -- 1. Index for filtering orders by date and status, covering customer_id CREATE INDEX idx_orders_date_status_cust ON orders (order_date, status, customer_id, order_id); -- 2. Index for filtering customers by country CREATE INDEX idx_customers_country_custid ON customers (country, customer_id); -- 3. Covering…

Response time: 17684ms · Tokens: 2520

qwen3.8-27b

The main reason this is slow is not just the SQL wording; it is the missing indexes. With only: ```sql orders(order_id) customers(customer_id) ``` the database has no useful indexes for: - `orders.order_date` - `orders.status` - `orders.customer_id` - `customers.country` - `order_items.order_id` - aggregate columns `quantity` / `unit_price` So it is likely scanning large portions of `orders`, `customers`, and especially `order_items`. --- ## 1. Optimized query One safer rewrite is to filter the orders/customers first, aggregate by integer keys, and join customer details after the expensive aggregation. ```sql SELECT t.order_id, t.order_date, c.customer_name, c.email, t.total_amount FROM ( SE…

Response time: 446257ms · Tokens: 27162

solar-pro4

## SQL Query Optimization Analysis ### Performance Bottlenecks 1. **Missing Indexes**: The current indexes on `orders(order_id)` and `customers(customer_id)` are not optimal for this query's WHERE, JOIN, and GROUP BY operations. 2. **Late Filtering**: The query filters after joining large tables, increasing intermediate result sizes. 3. **Expensive Aggregation**: Aggregating before filtering high-value orders adds unnecessary computation. --- ### ✅ Optimization Recommendations #### 1. Create Strategic Indexes ```sql -- For filtering orders by date and status CREATE INDEX idx_orders_date_status ON orders(order_date, status); -- For joining order_items efficiently CREATE INDEX idx_order_items_…

Response time: 25427ms · Tokens: 992

muse-spark-1.2

This query is slow due to missing indexes and inefficient filtering. With 10M rows and indexes only on `PKs`, it's doing 3 Full Table Scans + Hash Join + Filesort. Here is the optimized version and why: ### 1. Optimized Query ```sql -- Rewrite to help optimizer filter BEFORE joining/aggregating SELECT o.order_id, o.order_date, c.customer_name, c.email, agg.total_amount FROM customers c JOIN orders o ON o.customer_id = c.customer_id JOIN ( SELECT oi.order_id, SUM(oi.quantity * oi.unit_price) AS total_amount FROM order_items oi GROUP BY oi.order_id HAVING SUM(oi.quantity * oi.unit_price) > 100 ) AS agg ON agg.order_id = o.order_id WHERE c.country = 'US' AND o.order_date >= '2024-01-01' AND o.o…

Response time: 20049ms · Tokens: 2639

glm-5.3-flash

# Optimized Query ```sql SELECT o.order_id, o.order_date, c.customer_name, c.email, SUM(oi.quantity * oi.unit_price) AS total_amount FROM orders o JOIN customers c ON c.customer_id = o.customer_id JOIN order_items oi ON oi.order_id = o.order_id WHERE o.order_date >= '2024-01-01' AND o.order_date < '2025-01-01' AND c.country = 'US' AND o.status <> 'cancelled' GROUP BY o.order_id, o.order_date, c.customer_name, c.email HAVING SUM(oi.quantity * oi.unit_price) > 100 ORDER BY total_amount DESC; ``` ## Recommended Indexes ```sql -- Cover the date/status filter on orders CREATE INDEX idx_orders_date_status ON orders (order_date, status, customer_id); -- Speed up the country filter on customers CREA…

Response time: 17027ms · Tokens: 758

anthropic-claude-fable-5-1

## Diagnosis The query itself is reasonably written. The problem is almost entirely **missing indexes**, plus a couple of structural things that make the optimizer's job harder. With only `orders(order_id)` and `customers(customer_id)` indexed: 1. **`order_items` has no index on `order_id`** — this is the killer. The join `oi.order_id = o.order_id` has to either full-scan `order_items` for a hash join, or (worst case) do a nested loop with a full scan per order. On 10M rows this alone can account for nearly all the runtime. 2. **No index on `orders(order_date)`** — the date range filter is a full table scan. 3. **No index on `customers(country)`** — full scan of customers. 4. **`GROUP BY` on…

Response time: 54304ms · Tokens: 3604

muse-spark-1.3

This query is slow because it does the most expensive work on the most rows: 1. No usable index for filtering: `o.order_date, o.status, c.country, oi.order_id` have no index. With 10M rows you get full table scans + Hash Joins. 2. Join explosion then aggregate: it joins `orders x customers x order_items` (multiple rows per order) *then* `GROUP BY + HAVING + ORDER BY`. That creates a huge intermediate result to sort. 3. `o.status != 'cancelled'` and `ORDER BY total_amount DESC` with no `LIMIT` can't use an index and force a full sort. ### 1. Optimized query - filter first, aggregate second, join last Don't join everything then aggregate. Filter `orders`, aggregate only those `order_items`, th…

Response time: 26484ms · Tokens: 3280

gpt-6-astra

The most obvious issue is the missing index on `order_items(order_id)`. You also have no indexes supporting the customer-country or order-date filters. With 10 million rows, those access paths usually matter more than rearranging the SQL. The best plan depends on your database engine, how many orders fall in 2024, and how many customers are in the US. ## 1. Add indexes supporting filtering and joins These are reasonable starting points—check for equivalent indexes before creating them: ```sql CREATE INDEX idx_customers_country_customer ON customers (country, customer_id); CREATE INDEX idx_orders_customer_date ON orders (customer_id, order_date); CREATE INDEX idx_order_items_order ON order_it…

Response time: 25930ms · Tokens: 1269

gemini-3.8-flash

To optimize this query for a 10-million-row database, you need to address two major areas: **missing indexes** (which are the primary cause of the slowness) and **query structure** (specifically, premature joins and grouping by wide string columns). --- ### Step 1: Add Essential Indexes (Highest Impact) Without proper indexes, the database performs full table scans on all three tables. Run the following DDL statements: ```sql -- 1. Index for order_items join and computation (Covering Index) CREATE INDEX idx_order_items_order_id_calc ON order_items (order_id, quantity, unit_price); -- 2. Index for orders table filtering and customer join CREATE INDEX idx_orders_date_status_cust ON orders (ord…

Response time: 17703ms · Tokens: 3031

mercury-2.5

To optimize this query, we need to address full table scans and inefficient joins. The current indexes only support primary key lookups, leaving the filter and join conditions unprotected. ### Recommended Indexes Create the following indexes to accelerate filtering and joining: ```sql CREATE INDEX idx_orders_filter ON orders(order_date, status, customer_id); CREATE INDEX idx_order_items_id ON order_items(order_id); CREATE INDEX idx_customers_country ON customers(country, customer_id); ``` ### Optimized Query Using a Common Table Expression (CTE) forces the database to filter the `orders` table before performing expensive joins. ```sql WITH active_orders AS ( SELECT order_id, customer_id, ord…

Response time: 4645ms · Tokens: 2516

deepseek-v4.1-flash

The main problem is that the query filters/joins on columns that have no useful indexes. The only indexes are the primary-key-like indexes on `orders(order_id)` and `customers(customer_id)`, so the database likely scans `order_items` and possibly `orders`/`customers` heavily. ### Recommended indexes ```sql CREATE INDEX idx_orders_date_status_customer ON orders (order_date, status, customer_id, order_id); CREATE INDEX idx_customers_country_customer ON customers (country, customer_id, customer_name, email); CREATE INDEX idx_order_items_order_covering ON order_items (order_id, quantity, unit_price); ``` If your database supports `INCLUDE`, you can use covering indexes instead, e.g.: ```sql CREA…

Response time: 89219ms · Tokens: 9345

All comparison examples