[HN Gopher] C# strings silently kill your SQL Server indexes in ...
___________________________________________________________________
C# strings silently kill your SQL Server indexes in Dapper
Author : PretzelFisch
Score : 112 points
Date : 2026-03-06 22:55 UTC (1 days ago)
(HTM) web link (consultwithgriff.com)
(TXT) w3m dump (consultwithgriff.com)
| wvenable wrote:
| This really doesn't have anything to do with C#. This is your
| classic nvarchar vs varchar issue (or unicode vs ASCII). The same
| thing happens if you mix collations.
|
| I'm not sure why anyone would choose varchar for a column in 2026
| unless if you have some sort of ancient backwards compatibility
| situation.
| beart wrote:
| I agree with your first point. I've seen this same issue crop
| up in several other ORMs.
|
| As to your second point. VARCHAR uses N + 2 bytes where as
| NVARCHAR uses N*2 + 2 bytes for storage (at least on SQL
| Server). The vast majority of character fields in databases
| I've worked with do not need to store unicode values.
| _3u10 wrote:
| Generally if it stores user input it needs to support
| Unicode. That said UTF-8 is probably a way better choice than
| UTF-16/UCS-2
| SigmundA wrote:
| UTF-8 is a relatively new thing in MSSQL and had lots of
| issues initially, I agree it's better and should have been
| implemented in the product long ago.
|
| I have avoided it and have not followed if the issues are
| fully resolved, I would hope they are.
| kstrauser wrote:
| > UTF-8 is a relatively new thing in MSSQL and had lots
| of issues initially, I agree it's better and should have
| been implemented in the product long ago.
|
| Their insistence on making the rest of the world go along
| with their obsolete pet scheme would be annoying if I
| ever had to use their stuff for anything ever. UTF-8 was
| conceived in 1992, and here we are in 2026 with a
| reasonably popularly database still considering it the
| new thing.
| recursive wrote:
| In 92 it was a conference talk. In 98 it was adopted by
| the IETF. Point probably stands though.
| swasheck wrote:
| the data types were introduced with SQL Server 7 (1998)
| so i'm not sure it's accurate to state that it's
| considered as the new thing.
| SigmundA wrote:
| UTF-8 was introduced in SQL Server 2019:
|
| https://learn.microsoft.com/en-us/sql/sql-server/what-s-
| new-...
| da_chicken wrote:
| I would be more critical of Microsoft choosing to support
| UCS-2/UTF-16 if Microsoft hadn't completed their
| implementation of Unicode support in the 90s and then
| been pretty consistent with it.
|
| Meanwhile Linux had a years long blowout in the early
| 2000s over switching to UTF-8 from Latin-1. And you can
| still encounter Linux programs that choke on UTF-8 text
| files or multi-byte characters 30 years later (`tr` being
| the one I can think of offhand). AFAIK, a shebang is
| still incompatible with a UTF-8 byte order mark. Yes, the
| UTF-8 BOM is both optional and unnecessary, but it's also
| _explicitly allowed by the spec_.
| downsplat wrote:
| It's not really a Linux vs MS thing though. When Unicode
| first came out, it was 16-bit, so all the early adopters
| went with that. That includes Java, Windows, JavaScript,
| the ICU lintaries, LibreOffice and its predecessors,
| .NET, the C language (remember wchar_t?), and probably a
| few more.
|
| Utf8 turned out to be the better approach, and it's
| slowly taking over, but it was not only Linu/Unix that
| pushed it ahead, the entire networking world did,
| especially http. Props also to early perl for jumping
| straight to utf8.
|
| Still... Utf8's superiority was clear enough by 2005 or
| so, MS could and should have seen it by then instead of
| waiting until 2019 to add utf8 collations to its
| database. Funny to see Sql Server falling behind good old
| Mysql on such a basic feature.
| wvenable wrote:
| Database systems are inherently conservative -- once you
| add something you have to support it forever. Microsoft
| went hog wild on XML in the database and I haven't seen
| it used in over a decade now.
| Dwedit wrote:
| The one place UTF-16 massively wins is text that would be
| two bytes as UTF-16, but three bytes as UTF-8. That's
| mainly Chinese, Japanese, Korean, etc...
| wvenable wrote:
| > The vast majority of character fields in databases I've
| worked with do not need to store unicode values.
|
| This has not been my experience at all. Exactly the opposite,
| in fact. ASCII is dead.
| SigmundA wrote:
| Vast majority of text fields I see are coded values that
| are perfectly fine using ascii, but I deal mostly with
| English language systems.
|
| Text fields that users can type into directly especially
| multiline tend to need unicode but they are far fewer.
| simonask wrote:
| English has plenty of Unicode -- claiming otherwise is
| such a cliche...
|
| Unicode is a requirement everywhere human language is
| used, from Earth to the Boootes Void.
| NegativeLatency wrote:
| Also less awkward to make it right the first time,
| instead of explaining why someone can't type their name
| or an emoji
| SigmundA wrote:
| Specifically not talking about a name field
| SigmundA wrote:
| I am talking about coded values, like Status = 'A', 'B'
| or 'C'
|
| Taking double the space for this stuff is a waste of
| resources and nobody usually cares about extended
| characters here in English language systems at least they
| just want something more readable than integers when
| querying and debugging the data. End users will see
| longer descriptions joined from code tables or from app
| caches which can have unicode.
| kstrauser wrote:
| Those are all single byte characters in UTF-8.
| simonask wrote:
| No. Look closer.
| croes wrote:
| But nvarchar is UTF-16
| SigmundA wrote:
| We are talking nvarchar here, yes UTF-8 solves this issue
| completely and MSSQL supports it now days with varchar.
| wvenable wrote:
| It's _way_ better to just use a DBMS that supports enums.
| I know SQL server isn 't one of those but I still don't
| store my coded values as strings.
| andy81 wrote:
| The way to do enums in SQL (generally, not just MSSQL) is
| another table. It's better that they don't offer several
| ways to do the same thing.
| SigmundA wrote:
| Mostly agree separate tables can have multiple attributes
| besides a text description and can be exposed for
| modification to the application easily so users or
| administrators can add and modify codes.
|
| A common extra attribute for a coded value is something
| for deprecation / soft delete, so that it can be marked
| as no longer valid for future data but existing data can
| remain with that code, also date ranges its valid for
| etc, also parent child code relationships.
|
| Enums would be a good feature but they have a much more
| limited use case for static values you know ahead of time
| that will have no other attributes and values cannot be
| removed even if never used or old data migrated to new
| values.
|
| Common real world codes like US postal state can take
| advantage of there being agreed upon codes such as 'NY'
| and 'New York'.
| sgarland wrote:
| While I generally would prefer lookup tables, it's much
| easier to sell dev teams on "it looks and acts like a
| string - you don't have to change anything."
| SigmundA wrote:
| How do you store them? Also enums are not user
| configurable normally. It would be a good feature to have
| them, but they don't work well in many cases.
|
| Typical code tables with code, description and anything
| else needed for that value which the user can configure
| in the app.
|
| Sure you can use integers instead of codes, now all your
| results look like 1, 2, 3, 4 for all your coded columns
| when trying to debug or write ad-hoc stuff. Also ints are
| not variable length so your wasting space for short codes
| and you have to know ahead time if its only going to be
| 1,2,4 or 8 bytes.
| wvenable wrote:
| Enums are for non user-configurable values.
|
| For configurable values, obviously you use a table. But
| those should have an auto-integer primary key and if you
| need the description, join for it.
|
| Ints are by far more the efficient way to store and query
| these values -- the length of the string is stored as an
| int and variable length values really complicate storage
| and access. If you think strings save space or time that
| is not right.
| SigmundA wrote:
| >Enums are for non user-configurable values
|
| In the systems I work with most coded values are user
| configurable.
|
| >But those should have an auto-integer primary key and if
| you need the description, join for it.
|
| Not ergonomic now when querying data or debugging things
| like postal state are 11 instead of 'NY'
|
| select * from addresses where state = 11, no thanks.
|
| Your whole results set becomes a bunch of ints that can
| be easily transposed causing silly errors. Of course I
| have seen systems that use guids to avoid collision, boy
| is that fun, just use varchar or char if your penny
| pinching and ok with fixed sizes.
|
| >the length of the string is stored as an int
|
| No it's stored as a smallint 2 bytes. So a single
| character code is 3 bytes rather than a 4 byte int. 2
| chars is the same as an int. They do not complicate
| storage access in any meaningful way.
|
| You could use smallint or tinyint for your primary key
| and I could use char(2) and char(1) and get readable
| codes if I wanted to really save space.
| Slothrop99 wrote:
| Just to be pedantic, those characters are in
| 'ANSI'/CP1252 and would be fine in a varchar on many
| systems.
|
| Not that I disagree — Win32/C#/Java/etc have 16-bit
| characters, your entire system is already 'paying the
| price', so weird to get frugal here.
| simonask wrote:
| My comment contains two glyphs that are not in CP1252.
| zabzonk wrote:
| > Unicode is a requirement everywhere human language is
| used
|
| Strange then how it was not a requirement for many, many
| years.
| procaryote wrote:
| It was a mess back then though. Unicode fixed that.
| zabzonk wrote:
| I'm not convinced that Unicode fixed anything. I was kind
| of hoping, way back when, that everyone would adopt
| ASCII, as a step to a more united world. But things seem
| to have got more differentiated, and made things much
| more difficult.
| psidebot wrote:
| Some examples of coded fields that may be known to be
| ascii: order name, department code, business title, cost
| center, location id, preferred language, account type...
| SigmundA wrote:
| To complicate matters SQL Server can do Nvarchar compression,
| but they should have just done UTF-8 long ago:
|
| https://learn.microsoft.com/en-us/sql/relational-
| databases/d...
|
| Also UTF-8 is actually just a varchar collation so you don't
| use nvarchar with that, lol?
| SigmundA wrote:
| Yes I have run into this regardless of client language and I
| consider it a defect in the optimizer.
| wvenable wrote:
| I wouldn't consider it a defect in the optimizer; it's doing
| exactly what it's told to do. It cannot convert an nvarchar
| to varchar -- that's a narrowing conversion. All it can do is
| convert the other way and lose the ability to use the index.
| If you think that there is no danger converting an nvarchar
| that contains only ASCII to varchar then I have about 70+
| different collations that say otherwise.
| SigmundA wrote:
| Can you give an example whats dangerous about converting a
| nvarchar with only ascii (0-127) then using the index
| otherwise fallback to a scan?
|
| If we simply went to UTF-8 collation using varchar then
| this wouldn't be an issue either, which is why you would
| use varchar in 2026, best of both worlds so to speak.
| wvenable wrote:
| For a literal/parameter that happens to be ASCII, a
| person might know it would fit in varchar, but the
| optimizer has to choose a plan that stays correct in the
| general case, not just for that one runtime value. By
| telling SQL server the parameter is a nvarchar value,
| you're the one telling it that might not be ASCII.
| jstrong wrote:
| optimizer can't inspect the value? pretty dumb optimizer,
| then.
| wvenable wrote:
| Running the optimizer for every execution of the same
| query is... not very optimal.
| SigmundA wrote:
| It can run it for a range of values:
| https://learn.microsoft.com/en-us/sql/relational-
| databases/p...
|
| Also the simpler and maybe better approach is just make
| the decision every time as an operation in the plan,
| attempt the cast if it fails then scan and cast a many
| times the other way, if it succeeds then use the index,
| this isn't hard and adds one extra cast attempt on the
| slow path otherwise it does what everyone has to do
| manually in their code like this article but
| transparently.
|
| The adaptive join operator does something much more
| complex: https://learn.microsoft.com/en-
| us/sql/relational-databases/p...
| wvenable wrote:
| I'm not sure it makes sense to add more checks and
| another operation to every single query just for the case
| where the user explicitly mislabels the types. You're
| going to slow down everything everywhere (slightly) for a
| pretty obscure case. I suspect, in the long term, this
| would be a bad choice.
| SigmundA wrote:
| The check is added if it sees a varchar column and
| nvarchar parameter predicate on it.
|
| It currently just does a scan in that situation which
| orders of magnitude more expensive with a cast for every
| row vs a single extra cast check on the single parameter
| value that may avoid all those other casts in a common
| situation.
|
| There is no planning overhead, it's already detecting the
| situation. The execution overhead is a single extra cast
| on top of the cast per row, so n+1 vs n with the
| potential to eliminate n with a very common charset.
| zabzonk wrote:
| It's not "the value", it's "the values".
| munch117 wrote:
| Making a plan that works for the general case, but is
| also efficient, is rather trivial. Here's pseudocode from
| spending two minutes on the problem: #
| INPUT: lookfor: unicode var lower, upper: ascii
| lower = ascii_lower_bound(lookfor) upper =
| ascii_upper_bound(lookfor) for candidate:ascii in
| index_lookup(lower .. upper): if
| expensive_correct_compare_equal(candidate.field,
| lookfor): yield candidate
|
| The magic is to have functions ascii_lower_bound and
| ascii_upper_bound, that compute an ASCII string such that
| all ASCII strings that compare smaller (greater) cannot
| be equal to the input. Those functions are not hard to
| write. Although you might have to implement versions for
| each supported locale-dependent text comparison
| algorithm, but still, not a big deal.
|
| Worst case, 'lower' and 'upper' span the whole table -
| could happen if you have some really gnarly string
| comparison rules to deal with. But then you're no worse
| off than before. And most of the time you'll have
| lower==upper and excellent performance.
| applfanboysbgon wrote:
| I think this is a rather pertinent showcase of the danger of
| outsourcing your thinking to LLMs. This article strongly
| indicates to me that it is LLM-written, and it's likely the LLM
| diagnosed the issue as being a C# issue. When you don't
| understand the systems you're building with, all you can do is
| take the plausible-sounding generated text about what went
| wrong for granted, and then I suppose regurgitate it on your
| LLM-generated portfolio website in an ostensible show of your
| profound architectural knowledge.
| cosmez wrote:
| This is a common issue, and most developers I worked with are
| not aware of it until they see the performance issues.
|
| Most people are not aware of how Dapper maps types under the
| hood; once you know, you start being careful about it.
|
| Nothing to do with LLMs, just plain old learning through
| mistakes.
| keithnz wrote:
| actually, LLMs do way better, with dapper the LLM generates
| code to specify types for strings
| ziml77 wrote:
| This is not at all just an LLM thing. I've been working with
| C# and MS SQL Server for many years and never even considered
| this could be happening when I use Dapper. There's likely
| code I have deployed running suboptimally because of this.
|
| And it's not like I don't care about performance. If I see a
| small query taking more than a fraction of a second when
| testing in SSMS or If I see a larger query taking more than a
| few seconds I will dig into the query plan and try to make
| changes to improve it. For code that I took from testing in
| SSMS and moved into a Dapper query, I wouldn't have noticed
| performance issues from that move if the slowdown was never
| particularly large.
| dspillett wrote:
| _> I 'm not sure why anyone would choose varchar for a column
| in 2026_
|
| The same string takes roughly half the storage space, meaning
| more rows per page and therefore a smaller working set needed
| in memory for the same queries and less IO. Also, any indexes
| on those columns will also be similarly smaller. So if you are
| storing things that you know won't break out of the standard
| ASCII set0, stick with [VAR]CHARs1, otherwise use N[VAR]CHARs.
|
| Of course if you can guarantee that your stuff will be used on
| recent enough SQL Server versions that are configured to
| support UTF8 collations, then default to that instead unless
| you expect data in a character set where that might increase
| the data size over UTF16. You'll get the same size benefit for
| pure ASCII without losing wider character set support.
|
| Furthermore, if you are using row or page compression it
| doesn't really matter: your wide-character strings will
| effectively be UTF8 encoded anyway. But be aware that there is
| a CPU hit for processing compressed rows and pages every access
| because they remain compressed in memory as well as on-disk.
|
| --------
|
| [0] Codes with fixed ranges, etc.
|
| [1] Some would say that the other way around, and "use NVARCHAR
| if you think there might be any non-ASCIII characters", but
| defaulting to NVARCHAR and moving to VARCHAR only if you are
| confident is the safer approach IMO.
| gfody wrote:
| utf16 is more efficient if you have non-english text, utf8
| wastes space with long escape sequences. but the real reason
| to always use nvarchar is that it remains sargeable when
| varchar parameters are implicitly cast to nvarchar.
| exceptione wrote:
| What do you mean with non-english text? I don't think "A"
| will be more efficient in utf16 than in utf8. Or do you
| mean utf16 wins in cases of non-latin scripts with variable
| width? I always had the impression that utf8 wins on the
| vast majority of symbols, and that in case of very complex
| variable width char sets it depends on the wideness if
| utf16 can accommodate it. On a tangent, I wonder if emoji's
| would fit that bill too..
| Tuna-Fish wrote:
| Japanese, Chinese, Korean and Indic scripts are mostly 2
| bytes per character on UTF-16 and mostly 3 bytes per
| character in UTF-8.
| divingdragon wrote:
| Really, as an East Asian language user the rest of the
| comments here make me want to scream.
| gfody wrote:
| hn often makes me want to scream
| exceptione wrote:
| I am not sure if you mean me, as I just asked a question.
| I wonder what the best way is to handle this disparity
| for international software. It seems like either you
| punish the Latin alphabets, or the others.
| tialaramex wrote:
| UTF-16 is _maybe_ better if your text is _mostly_ made of
| codepoints which need 3 UTF-8 code units but only one (thus
| 2 bytes) UTF-16 code unit. This is extremely rare for
| general text and so you definitely shouldn 't begin by
| assuming UTF-16 is a good choice without having collected
| actual data.
| downsplat wrote:
| The old defense of 16-bit chars, popping up in 2026 still!
| Utf8 is efficient enough for all general purpose uses.
|
| If you're storing gigabytes of non-latin-alphabet text, and
| your systems are constrained enough that it makes a
| difference, 16-bit is always there. But I'd still recommend
| anyone starting a system today to not worry and use utf8
| for everything.j
| gfody wrote:
| it certainly isn't the best choice for sql server, see:
| https://sqlquantumleap.com/2018/09/28/native-
| utf-8-support-i...
| SigmundA wrote:
| The non sargeablilty is an optimizer deficiency IMO. It
| could attempt to cast just like this article is doing
| manually in code, if that success use index, if it fails
| scan and cast a million times the other way in a scan.
| gfody wrote:
| implicit casts should only widen to avoid quiet
| information loss, if the optimizer behaved as you suggest
| the query could return incorrect results and potentially
| more than expected, with even worse consequences
| SigmundA wrote:
| It should not return incorrect results, if the nvarchar
| only contains ascii it will cast perfectly, if it doesn't
| then do the slow scan path, it's a simple check and the
| same work its doing for every row in the current behavior
| except one time and more restricted. Can you give me an
| example of an incorrect result here?
|
| I am not talking about the default cast behavior from
| nvarchar to varchar, but a specific narrow check the
| optimizer can use to make decision in the plan of ascii
| or not with no information loss because it will do the
| same thing as before if it does not pass the one time
| parameter check.
|
| By far the most common cause of this situation is using
| ascii only in a nvarchar because like say in this example
| the client language is using an nvarchar equivalent for
| all strings, which is pretty much universal now days and
| that is the default conversion when using a sql client
| library, one must remember to explicitly cast rather than
| the db doing it for you which is the expected behavior
| and the source of much confusion.
|
| This would be purely an optimization fast path check
| otherwise fall back to the current slow path, correct
| results always with much faster results if only ascii is
| present in the string.
| paulsutter wrote:
| Utf8 solved this completely. It works with any length unicode
| and on average takes up almost as little storage as ascii.
|
| Utf16 is brain dead and an embarrassment
| wvenable wrote:
| Blame the Unicode consortium for not coming up UTF-8 first
| (or, really, at all). And for assuming that 65526 code points
| would be enough for everyone.
|
| So many problems could be solved with a time machine.
| kstrauser wrote:
| The first draft of Unicode was in 1988. Thompson and Pike
| came up with UTF-8 in 1992, made an RFC in 1998. UTF-16
| came along in 1996, made an RFC in 2000.
|
| The time machine would've involved Microsoft saying "it's
| clear now that USC-2 was a bad idea, so let's start
| migrating to something genuinely better".
| gpvos wrote:
| MS could easily have added proper UTF-8 support in the
| early 2000s instead of the late 2010s.
| kstrauser wrote:
| Yep. It would've been a better landing pad than UTF-16
| since they had to migrate off UCS-2 anyway.
| wvenable wrote:
| I don't think it was clear at the time that UTF-8 would
| take off. UCS-2 and then UTF-16 was _well_ established by
| 2000 in both Microsoft technologies and elsewhere (like
| Java). Linux, despite the existence of UTF-8, would still
| take years to get acceptable internationalization
| support. Developing good and secure internationalization
| is a hard problem -- it took a long time for everyone.
|
| It's now 2026, everything always looks different in
| hindsight.
| kstrauser wrote:
| I don't remember it quite that way. Localization was a
| giant question, sure. Are we using C or UTF-8 for the
| default locale? That had lots of screaming matches. But
| in the network service world, I don't remember ever
| hearing more than a token resistance against choosing
| UTF-8 as the successor to ASCII. It was a huge win,
| especially since ASCII text is already valid UTF-8 text.
| Make your browser default to parsing docs with that
| encoding and you can still parse all existing ASCII docs
| with zero changes! That was a huge, enormous selling
| point.
|
| Windows is far from a niche player, to be sure. Yet it
| seems like literally every other OS but them was going
| with one encoding for everything, while they went in a
| totally different direction that got complaints even
| then. I truly believe they thought they'd win that battle
| and eventually everyone else would move to UTF-16 to join
| them. Meanwhile, every other OS vendor was like, nah, no
| way we're rewriting everything from scratch to work with
| a not-backward compatible encoding.
| wvenable wrote:
| Microsoft did the hard work of supporting Unicode when
| UTF-8 didn't exist (and mostly when UTF-16 didn't exist).
|
| Any system that continued with only ASCII well into the
| 2000s could mostly just jump into UTF-8 without issue.
| Doing nothing for non-English users for almost two
| decades turned out to be a solid plan long term.
| Microsoft certainly didn't have that option.
| Dwedit wrote:
| It gets worse for UTF-16, Windows will let you name files
| using unpaired surrogates, now you have a filename that
| exists on your disk that cannot be represented in UTF-8 (nor
| compliant UTF-16 for that matter). Because of that, there's
| yet another encoding called WTF-8 that can represent the
| arbitrary invalid 16-bit values.
| croes wrote:
| Since MS SQL Server 2019 varchar supports unicode so now it's
| the opposite, you use nvarchar instead of varchar for backwards
| compatibility reasons.
| jiggawatts wrote:
| This feels like a bug in the SQL query optimizer rather than
| Dapper.
|
| It ought to be smart enough to convert a constant parameter to
| the target column type in a predicate constraint _and then_ check
| for the availability of a covering index.
| wvenable wrote:
| It's the optimizer caching the query plan as a parameterized
| query. It's not re-planning the index lookup on every
| execution.
| SigmundA wrote:
| The parameter type is part of the cache identity, nvarchar
| and varchar would have two cache entries with possibly
| different plans.
| valiant55 wrote:
| There's a data type precedence that it uses to determine which
| value should be casted[0]. Nvarchar is higher precedence,
| therefore the varchar value is "lifted" to an nvarchar value
| first. This wouldn't be an issue if the types were reversed.
|
| 0: https://learn.microsoft.com/en-us/sql/t-sql/data-
| types/data-...
| beart wrote:
| How do you safely convert a 2 byte character to a 1 byte
| character?
| jiggawatts wrote:
| Easily! If it doesn't convert successfully because it
| includes characters outside of the range of the target
| codepage then the equality condition is necessarily false,
| and the engine should short-circuit and return an empty set.
| enord wrote:
| This is due to utf-16, an unforgivable abomination.
| adzm wrote:
| even better is Entity Framework and how it handles null strings
| by creating some strange predicates in SQL that end up being
| unable to seek into string indexes
| smithkl42 wrote:
| Been bit by that before: it's not just an issue with Dapper, it
| can also hit you with Entity Framework.
| andrelaszlo wrote:
| I thought, having just read the title, that maybe it's time to
| upgrade if you're still on Ubuntu 6.06.
| briHass wrote:
| I've found and fixed this bug before. There are 2 other ways to
| handle it
|
| Dapper has a static configuration for things like TypeMappers,
| and you can change the default mapping for string to use varchar
| with: Dapper.SqlMapper.AddTypeMap(typeof(string),System.Data.DbTy
| pe.AnsiString). I typically set that in the app startup, because
| I avoid NVARCHAR almost entirely (to save the extra byte per
| character, since I rarely need anything outside of ANSI.)
|
| Or, one could use stored procedures. Assuming you take in a
| parameter that is the correct type for your indexed predicate,
| the conversion happens once when the SPROC is called, not done by
| the optimizer in the query.
|
| I still have mixed feelings about overuse of SQL stored
| procedures, but this is a classic example of where on of their
| benefits is revealed: they are a defined interface for the
| database, where DB-specific types can be handled instead of
| polluting your code with specifics about your DB.
|
| (This is also a problem for other type mismatches like
| DateTime/Date, numeric types, etc.)
| ziml77 wrote:
| Sprocs are how I handle complex queries rather than embedding
| them in our server applications. It's definitely saved me from
| running into problems like this. And it comes with another
| advantage of giving DBAs more control to manage performance
| (DBAs do not like hearing that they can't take care of a
| performance issue that's cropped up because the query is
| compiled into an application)
| bonesss wrote:
| As a general issue of hygiene I tend to wrap any ORM and access
| it through an internal interface.
|
| 1) The joy of writing and saying DapperWrapper can't be
| overstated.
|
| 2) in conjunction with meaningful domain types it lets you
| handle these issues across the app at a single point of
| control, and capture more domain semantics for testing.
| maciekkmrk wrote:
| Interesting problem, but the AI prose makes me not want to read
| to the end.
| diath wrote:
| It's weird that the article does not show any benchmarks but
| crappy descriptions like "milliseconds to microseconds" and "tens
| of thousands to single digits". This is the kind of vague
| performance description LLMs like to give when you ask them about
| performance differences between solutions and don't explicitly
| ask for a benchmark suite.
| _vertigo wrote:
| > No schema changes. No new indexes. No query rewrites. Just
| telling Dapper the correct parameter type.
| pllbnk wrote:
| Are we automatically discarding everything that might or
| might not have been written or assisted by an LLM? I get it
| when the articles are the type of meaningless self
| improvement or similar kind of word soup. However, if
| hypothetically an author uses LLM assistance to improve their
| styling to their liking, I see nothing wrong with that as
| long as the core message stands out.
| rmunn wrote:
| I've seen so many LLM-generated articles by this point that
| obviously had no human editing done beforehand -- just
| prompt and slap it onto the Web -- that it makes me wonder
| every time. If I read this article, will I actually learn
| only _truth_? Or are there some key parts of this article
| that are actually _false_ because the LLM hallucinated
| them, and the human involved didn 't bother to double-check
| the article before publishing it?
|
| If someone was just using the LLM for style, that's fine.
| But if they were using it for content, I just can't trust
| that it's accurate. And the time cost for me to read the
| article just isn't worth it if there's a chance it's wrong
| in important ways, so when I see obvious signs of LLM use,
| I just skip and move on.
|
| Now, if someone _acknowledged_ their LLM use up front and
| said "only used for style, facts have been verified by a
| human" or whatever, then I'd have enough confidence in the
| article to spend the time to read it. But unacknowledged
| LLM use? Too great a risk of uncorrected hallucinations, in
| my experience, so I'll skip it.
| pllbnk wrote:
| I disagree. I think it's a nice discovery many might be unaware
| of and later spend a lot of time on tracking down the
| performance issue independently. I also disagree that a
| rigorous benchmark is needed for every single performance-
| related blog post because good benchmarks are difficult to
| write, you have to account for multiple variables. Here, the
| author just said - "trust me, it's much faster" and I trust
| them because they explained the reasoning behind the
| degradation.
| nmeofthestate wrote:
| The writing style certainly screams LLM.
| mvdtnz wrote:
| This is a really interesting blog post - the kind of old school
| stuff the web used to be riddled with. I must say - would it have
| been that hard to just write this by hand? The AI adds nothing
| here but the same annoying old AI-isms that distract from the
| piece.
| ltbarcly3 wrote:
| Life is too short to use SQL Server. I know people that use it
| will swear it's "not bad anymore" but yes it is.
| bni wrote:
| yes it is
| pjmlp wrote:
| I never had this issue with Dapper, as others point out, an
| holding it wrong problem.
| downsplat wrote:
| Did this post come out of a freezer from 1998? Who on earth
| creates databases in Latin1 in 2026?
|
| Nevermind, looks like Sql Server didn't add utf8 collations until
| 2019 (!) and for decades people had to choose column by column
| between the 16-bit overhead of "nvarchar" and latin1... And still
| do if they want a bit of backwards compatibility. Amazing.
| rmunn wrote:
| "Just use Postgres" (which defaults to UTF-8 encoding unless
| specifically configured to use something else) is looking like
| better and better advice every day.
|
| Doesn't help those tied to legacy systems that would require a
| huge, expensive effort to upgrade, though. Sorry, folks.
| There's a better system, you know it's a better system, and you
| can't use it because switching is too expensive? I've been
| there (not databases, in my case) and it truly sucks.
| elmigranto wrote:
| Third party dependencies are very easy: you just have to
| intimately know how it is implemented in addition to knowing your
| own code and stack, and then you are golden!
|
| Nothing to learn, just focus on making your app, it's all taken
| care of by This One Simple Package ;)
|
| These things are so far from free as our tooling presents with
| "just nuget it or whatever".
| DeathMetal3000 wrote:
| I'm sure writing their own ORM would have given them
| instantaneous insight into this issue and introduced no other
| challenges. Open source developers hate this one weird trick!
| elmigranto wrote:
| Especially for things used directly, you need to understand
| both, own and third party code, roughly to the same level.
| With own code, you only care for your own use case; with
| third-party -- you have to kind of get everyone else's.
|
| Depending on what you do and the dependency's scope, either
| way can make sense.
| bunbun69 wrote:
| AI slop article
|
| Also no meaningful benchmarking was done
___________________________________________________________________
(page generated 2026-03-07 23:01 UTC)