{"slug": "kiro-as-ai-partner-for-ms-sql-server-optimization-on-net-core-yang-biasa-berhari", "title": "Kiro as AI Partner for MS SQL Server Optimization on .NET Core: Yang Biasa Berhari-hari, Sekarang Hitungan Jam", "summary": "A developer used Kiro, an AI partner, to optimize MS SQL Server query performance on a .NET Core application, reducing investigation time from days to hours. Kiro analyzed raw queries and codebase context to identify critical issues like high read latency, missing indexes, and inefficient ORM eager loading. The collaboration involved the developer executing diagnostic queries manually and feeding results back to Kiro for analysis.", "body_md": "Dulu, nyari query yang bikin database spike itu bisa makan berhari-hari. Yang nyari capek, yang nge-fix juga capek. Sekarang? Hitungan jam — dan bonusnya, sambil belajar hal baru juga.\n\nCeritanya begini. Kalau kamu pernah kerja di aplikasi yang pakai ORM (Object-Relational Mapping — semacam \"penerjemah otomatis\" antara code dan database), pasti familiar sama situasi ini: database tiba-tiba lambat, kamu dapet raw query yang jadi biang kerok, tapi di codebase kamu nulis pakai syntax ORM yang bentuknya beda jauh dari SQL mentah itu.\n\nBuat yang belum pernah deal sama ORM, bayangin gini: kamu nulis pesan dalam bahasa Indonesia, lalu ada \"penerjemah otomatis\" yang convert jadi bahasa Jepang sebelum dikirim ke penerima. Suatu hari ada masalah di pesan yang terkirim — tapi kamu cuma bisa lihat versi bahasa Jepang-nya. Nyari bagian mana dari tulisan Indonesia kamu yang bikin terjemahan-nya bermasalah? Itu effort-nya yang bikin pengen balik tidur aja.\n\nSekarang dengan bantuan Kiro, cukup kasih raw query + akses ke codebase, dia otomatis nyari bagian mana di code yang nge-generate query bermasalah itu. Yang dulu butuh berhari-hari, sekarang bisa selesai dalam hitungan jam — dan itu baru tahap investigasi, belum termasuk fixing-nya.\n\nAkhir-akhir ini lagi aktif pakai Kiro di tempat kerja. Awal tahun lalu kantor dapat credits melalui program [Kiro for Startup](https://kiro.dev/startups/), jadi ya sekalian dimaksimalkan.\n\nSelain buat debug dan explore query di MS SQL Server, kadang pakai Kiro juga buat analisa log AWS CloudWatch — sambil kasih context aplikasi yang running biar analisa-nya lebih akurat dan gak generic.\n\nDi tulisan kali ini, saya mau sharing gimana pakai Kiro sebagai *partner* beberapa minggu terakhir buat improve query performance di aplikasi .NET Core. Kenapa \"partner\"? Karena Kiro-nya gak boleh langsung akses ke database — jadi wajib melalui perantara saya. Kita discuss, kolaborasi, dan nge-solve bareng. Bukan AI yang dikasih tombol terus disuruh jalan sendiri.\n\nBeberapa waktu lalu, metrics database kami menunjukkan alarm — data I/O sering spike. Ini harus dicek dan di-improve sebelum user mulai ngerasain.\n\nDulu kayak yang saya bilang tadi — ini pekerjaan yang paling malas saya kerjakan. Ribet-nya di level: kita cuma dapet raw query yang di-generate ORM, sementara di codebase kita nulis pakai syntax yang bentuknya jauh berbeda. Gak langsung ketahuan code bagian mana yang nge-generate query lambat itu.\n\nBuat gambaran lebih simpel: ORM itu kayak kamu bilang ke asisten \"ambilin data pesanan yang aktif, urutin dari yang terbaru ya.\" Si asisten nerjemahin instruksi itu jadi perintah teknis ke database. Nah kalau ternyata cara dia nerjemahin gak efisien dan bikin database lambat, kamu harus reverse-engineer dari hasil terjemahan teknis itu balik ke instruksi awalmu — dan *itu* yang bikin pusing.\n\nKarena database gak bisa dikasih akses langsung ke AI, maka flow-nya begini: Kiro kasih instruksi query apa yang perlu saya jalankan, saya eksekusi di database, dan hasilnya saya kirim balik ke dia untuk dianalisa.\n\nSaya mulai dengan kasih context:\n\n\"Saya punya database MS SQL Server yang beberapa menit lalu spike data I/O-nya. Kita akan cari tahu proses/query apa penyebabnya. Kamu info ke saya query apa yang perlu dijalankan, nanti saya yang eksekusi dan kirim hasilnya untuk kamu analisa.\"\n\nDari situ, Kiro kasih beberapa diagnostic query yang perlu saya run:\n\nSetelah saya jalankan semua dan kirim hasilnya, Kiro langsung menganalisa dan kasih output yang cukup komprehensif — dari executive summary sampai rencana aksi per-priority.\n\nKiro kasih temuan lengkap dengan severity level:\n\n| Temuan | Severity |\n|---|---|\n| Read latency sangat tinggi (130-169ms avg) | 🔴 Critical |\n| 86% wait time = PAGEIOLATCH_SH (read I/O) | 🔴 Critical |\n| Missing index pada kolom filter utama | 🔴 Critical |\n| 3 index tidak pernah dibaca (0 reads, 24K+ writes) | 🟡 Warning |\n| Eager loading sebelum pagination di ORM | 🔴 Critical |\n\nYang menarik, dia gak berhenti di level database. Dia langsung identify pattern di code yang bermasalah:\n\n``` js\n// Pattern bermasalah yang ditemukan Kiro:\nvar data = _db.Orders\n    .Include(a => a.OrderItems)      // ← Eager load SEMUA items dulu\n    .AsNoTracking()\n    .Where(x => x.TenantId == tenantId && !x.Deleted)\n    .OrderByDescending(x => x.UpdatedAt)\n    .Skip(page * size)\n    .Take(size)\n    .ToListAsync();\n```\n\nBuat non-.NET developer: `.Include()`\n\nitu kayak bilang \"sekalian ambilin semua data relasi-nya juga.\" Masalahnya ini ditaruh *sebelum* pagination — artinya database load semua data beserta relasi-nya ke memory dulu, baru dipotong per halaman. Kalau datanya jutaan rows? Ya Out of Memory.\n\nKiro kasih rekomendasi fix dengan pendekatan 2-step:\n\n``` js\n// Step 1: Ambil ID aja dulu (ringan, tanpa relasi)\nvar pagedIds = await _db.Orders\n    .Where(x => x.TenantId == tenantId && !x.Deleted)\n    .OrderByDescending(x => x.UpdatedAt)\n    .Skip(page * size)\n    .Take(size)\n    .Select(x => x.Id)\n    .ToListAsync();\n\n// Step 2: Baru load full data + relasi, cuma untuk ID yang sudah di-page\nvar result = await _db.Orders\n    .Include(a => a.OrderItems)\n    .AsNoTracking()\n    .Where(x => pagedIds.Contains(x.Id))\n    .ToListAsync();\n```\n\nKonsepnya universal: jangan load semua dulu baru potong — potong dulu, baru load yang diperlukan. Ini applicable di framework dan bahasa apapun yang punya ORM.\n\nSelain fix di level code, Kiro juga kasih rencana aksi di level database:\n\nKalau dilihat rencana aksi di atas, Kiro gak cuma menganalisa raw query yang lambat terus kasih saran generic \"tambahin index.\" Yang bikin beda: dia juga mempelajari code backend .NET Core yang jadi sumber query tersebut.\n\nJadi misalnya dari raw query yang lambat, dia langsung bisa trace sendiri — \"Oh ini query-nya di-generate dari `OrderController.GetDataTableParams`\n\n, line sekian, di repository method `GetOrdersWithDateFilter`\n\n.\" Saya gak perlu kasih tahu file mana — dia cari sendiri di codebase.\n\nDari situ saran-nya jadi spesifik ke situasi kita, bukan template jawaban:\n\n`.Include()`\n\nyang posisinya bikin database load jutaan row sebelum pagination jalan — itu saran refactor di level code, bukan di level database.Ini yang beda dari cuma kasih satu potongan query ke AI terus minta pendapat. Karena Kiro punya akses ke seluruh codebase, dia bisa connect the dots — dari \"query lambat di database\" ke \"code pattern di aplikasi yang nge-generate query itu\" — dan kasih solusi yang nyambung di kedua sisi sekaligus.\n\nHal yang sering saya dengar: \"AI bikin kita makin bodoh dan malas belajar.\" Pengalaman saya di case ini justru kebalikannya.\n\nBegini ceritanya. Waktu Kiro nemuin pattern bermasalah di codebase, dia gak cuma bilang \"ini salah, ganti jadi begini.\" Dia jelaskan *kenapa* itu salah, apa yang terjadi di balik layar, dan kapan pattern itu sebenernya boleh dipakai. Dan saya — yang udah bertahun-tahun nulis code .NET — baru ngeh beberapa hal fundamental yang selama ini terlewat.\n\nYang bikin ini jadi \"teman belajar\" dan bukan sekadar autocomplete pintar: setiap kali Kiro nemuin sesuatu yang menarik, saya minta dia jelaskan lebih detail dan simpan jadi file markdown tersendiri. Judulnya saya buat kayak catatan belajar — *\"What I Learned Today: Kenapa .ToLower() di LINQ Query Bikin Database Lambat.\"*\n\nFile-file itu kemudian saya generate jadi PDF dan share ke Slack tim. Jadi bukan cuma saya yang belajar — satu tim ikut dapat insight-nya.\n\nIni beberapa contoh yang saya pelajari dari proses ini:\n\n`.ToLower()`\n\ndi ORM Query Ternyata Bikin Database Lambat\n\nKiro nemuin pattern ini tersebar di banyak repository:\n\n``` js\n// ❌ Bikin index gak bisa dipakai\ndb.Products.Any(x => x.Code.ToLower() == code.ToLower());\n```\n\nKenapa bermasalah? ORM nerjemahin `.ToLower()`\n\njadi function `LOWER()`\n\ndi SQL. Ketika ada function yang di-apply ke kolom database di `WHERE`\n\nclause, index jadi gak bisa dipakai — SQL Server harus scan semua row satu per satu.\n\nDi tabel dengan 1.6 juta rows: yang harusnya < 1 milidetik jadi 2-5 detik. Dan di case kita, function ini dipanggil ~2,400 kali dalam 1 jam. Itu artinya 2,400 full table scan yang seharusnya gak perlu.\n\nTernyata database kami pakai collation Case Insensitive (`CI`\n\n) — artinya perbandingan string sudah otomatis case-insensitive tanpa perlu function apapun:\n\n```\n// ✅ Index terpakai, hasil sama karena collation DB sudah CI\ndb.Products.Any(x => x.Code == code);\n```\n\nYang Kiro jelaskan dan bikin saya \"ohhh\" itu bedanya context: kalau query-nya ke database (LINQ-to-SQL), `.ToLower()`\n\ngak perlu karena collation yang handle. Tapi kalau data sudah di-load ke memory (LINQ-to-Objects), `.ToLower()`\n\natau `StringComparison.OrdinalIgnoreCase`\n\ntetap wajib karena C# itu case-sensitive. Syntax-nya sama, behavior-nya beda total tergantung context. Bertahun-tahun nulis LINQ dan baru kali ini benar-benar paham bedanya.\n\n**Kondisi OR yang Ternyata Redundan**\n\nPattern ini ditemukan di fitur sync mobile:\n\n``` js\n// ❌ Redundan dan bikin index gak optimal\n.Where(a => a.UpdatedAt >= param || a.CreatedAt >= param)\n```\n\nDua masalah:\n\n`OR`\n\ndi dua kolom berbeda bikin database gak bisa pakai index secara efisien — harus scan dua range terpisah lalu merge hasilnya`CreatedAt`\n\nitu `UpdatedAt`\n\ndi-set sama dengan `CreatedAt`\n\n. Dan setiap kali di-update, cuma `UpdatedAt`\n\nyang berubah. Jadi `UpdatedAt`\n\nselalu >= `CreatedAt`\n\nYang bikin ini jadi momen belajar: Kiro gak cuma bilang \"hapus aja OR-nya.\" Dia trace ke `SaveChangesHelper`\n\ndi codebase, tunjukin logic-nya — bahwa di entity lifecycle kita, `UpdatedAt`\n\nselalu di-set bareng `CreatedAt`\n\nsaat insert, dan cuma `UpdatedAt`\n\nyang berubah saat update. Jadi secara matematis, kondisi OR itu gak pernah menambah hasil apapun.\n\nCukup:\n\n``` js\n// ✅ Satu kondisi, index optimal\n.Where(a => a.UpdatedAt >= param)\n```\n\nDan masih ada beberapa hal lain yang saya pelajari — cukup banyak sampai sepertinya perlu dipisah jadi artikel tersendiri nanti.\n\nPoint-nya: selagi kita bisa prompting dengan tepat dan punya curiosity buat nanya \"kenapa?\", AI malah jadi accelerator buat belajar. Dia bukan pengganti berpikir — dia pembuka pintu ke hal-hal yang selama ini gak kita tahu ada. Dan kalau kita rajin simpan insight-nya, satu sesi belajar bisa jadi knowledge sharing buat satu tim.\n\nIni bagian yang menurut saya paling impactful.\n\nSetelah diskusi panjang — bolak-balik kirim query, terima analisa, diskusi solusi — saya mulai sadar: *\"Pattern-nya udah ketemu. Kalau besok database lain spike, masa harus ulang dari awal lagi?\"*\n\nJadi saya minta ke Kiro: **dari diskusi kita hari ini, formalisasi jadi sesuatu yang reusable.**\n\nKonkretnya:\n\n`sql-audit/`\n\n— pisahkan per file berdasarkan tujuannyaDan Kiro langsung eksekusi. Hasilnya:\n\n**Folder sql-audit/** — semua diagnostic query tersusun rapi per file sesuai urutan investigasi. Kedepannya kalau ada masalah I/O, gak perlu mikir \"harus mulai dari mana?\" — tinggal buka folder, run satu per satu.\n\n| # | File | Tujuan |\n|---|---|---|\n| 1 | `01_top_io_queries.sql` |\nTop query penyebab I/O historis |\n| 2 | `02_currently_running_io_heavy.sql` |\nQuery yang berjalan saat spike |\n| 3 | `03_io_stats_per_database_file.sql` |\nLatency per database file |\n| 4 | `04_io_wait_stats.sql` |\nWait type I/O yang dominan |\n| 5 | `05_current_indexes.sql` |\nReview semua index |\n| 6 | `06_index_usage_stats.sql` |\nIndex terpakai atau sia-sia |\n| 7 | `07_missing_indexes.sql` |\nRekomendasi index dari SQL Server |\n| 8 | `08_index_physical_stats.sql` |\nFragmentasi index |\n| 9 | `09_azure_resource_stats.sql` |\nResource usage (Azure) |\n| 10 | `10_io_per_table.sql` |\nTabel dengan I/O tertinggi |\n\n**Template Prompt** (`db-query-optimization-prompt.md`\n\n) — instruksi lengkap: apa yang harus Kiro analisa, format output yang diharapkan, severity classification, dan rencana aksi yang harus di-generate. Semacam \"SOP\" yang tinggal dipanggil.\n\nSekarang kalau ada database spike, flow saya literally cuma:\n\n```\nMenggunakan prompt di bawah ini, tolong analisa hasil performance database ini.\n\nFile prompt: query-optimization/db-query-optimization-prompt.md\nHasil SQL audit terbaru: /sql-audit\n```\n\nDone. Gak ada diskusi panjang lagi. Gak ada \"eh kemarin kita bahas apa ya.\" Semuanya sudah ter-encode di template.\n\n**Takeaway-nya**: diskusi panjang sama AI itu berharga, tapi lebih berharga lagi kalau kamu convert hasilnya jadi checkpoint yang reusable. Banyak orang pakai AI tapi knowledge dari diskusi-nya \"buang\" begitu aja — chat ditutup, ilang. Padahal kamu bisa minta AI-nya formalisasi jadi prompt template, folder terstruktur, atau workflow yang bisa jalan tanpa context sebelumnya.\n\nSatu masalah lagi yang muncul di awal-awal: gimana melanjutkan progress lintas hari?\n\nContohnya, tanggal 13 kita temuin masalah dan apply fix. Tapi butuh beberapa hari buat lihat impact-nya. Pas mau lanjut diskusi tanggal 15 atau 28, chat sebelumnya sudah tertutup dan ribet nyarinya.\n\nSolusinya simpel: setiap selesai satu session analisa, minta Kiro simpan hasilnya ke file dengan format tanggal:\n\n`query-optimization/orders-db/2026-05-13_initial_analysis.md`\n\n`query-optimization/orders-db/2026-05-28_follow_up_review.md`\n\nDi dalamnya tercatat semua: temuan, saran, yang sudah di-fix, yang belum, reasoning di balik setiap keputusan. Termasuk hal kayak \"tanggal 13 Kiro sarankan buat index X, tapi di follow-up tanggal 28 minta dihapus karena setelah code di-refactor ternyata gak efektif lagi.\"\n\nJadi prompt selanjutnya tinggal:\n\n```\nAnalisa hasil performance database ini.\n- File prompt: db-query-optimization-prompt.md\n- Hasil SQL audit terbaru: /sql-audit\n- Konteks diskusi sebelumnya: query-optimization/orders-db/\n```\n\nKiro langsung punya full context. Diskusinya berkelanjutan, saling melengkapi, dan AI-nya dapat gambaran luas tanpa harus dijelaskan ulang dari nol setiap session baru.\n\nYang gak saya sangka — folder change log itu ternyata punya kehidupan kedua. Sekarang folder itu jadi bagian dari code review automation.\n\nSalah satu rule di code review skill agent kami:\n\n\"Pastikan perubahan code mengikuti best practice dan menghindari kesalahan yang pernah dilakukan — datanya ada di folder\n\n`query-optimization/`\n\n. Pastikan setiap perubahan baru optimal dari sisi query maupun index.\"\n\nJadi saat AI melakukan code review pull request developer, dia juga cross-check sama history kesalahan yang pernah terjadi. Feedback loop-nya tertutup — kesalahan yang sama diminimalisir tanpa bergantung pada ingatan manusia.\n\nDari yang awalnya cuma \"debug database spike,\" sekarang jadi:\n\nSatu masalah, lima output. Gak direncanakan dari awal — tapi karena setiap langkah dibikin reusable, domino-nya jalan sendiri.\n\nItu sharing kali ini. Kiro bukan cuma bikin kerjaan lebih cepat — tapi juga bikin proses belajar lebih terstruktur, workflow lebih repeatable, dan knowledge gak hilang di chat yang tertutup.\n\nYang capek bukan database-nya. Yang capek itu manusia yang harus ulang-ulang proses yang sama tanpa sistem.\n\nSampai jumpa di tulisan selanjutnya. 🙌\n\n**About Me**\n\nHalo, nama saya [Ifan Jaya Suswanto Zalukhu](https://www.linkedin.com/in/ifanzalukhu97/). Di tahun 2026 ini adalah tahun kedua sebagai [AWS Community Builder](https://builder.aws.com/community/@ifanzalukhu97), sekaligus Co-Lead [AWS User Group Medan](https://www.meetup.com/aws-user-group-medan/). Suka sharing dan excited belajar hal baru — terutama di intersection cloud, AI, dan engineering productivity.", "url": "https://wpnews.pro/news/kiro-as-ai-partner-for-ms-sql-server-optimization-on-net-core-yang-biasa-berhari", "canonical_source": "https://dev.to/kirodotdev/kiro-as-ai-partner-for-ms-sql-server-optimization-on-net-core-yang-biasa-berhari-hari-sekarang-3h07", "published_at": "2026-06-13 18:55:19+00:00", "updated_at": "2026-06-13 19:14:41.898216+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "artificial-intelligence"], "entities": ["Kiro", "MS SQL Server", ".NET Core", "AWS CloudWatch", "Kiro for Startup"], "alternates": {"html": "https://wpnews.pro/news/kiro-as-ai-partner-for-ms-sql-server-optimization-on-net-core-yang-biasa-berhari", "markdown": "https://wpnews.pro/news/kiro-as-ai-partner-for-ms-sql-server-optimization-on-net-core-yang-biasa-berhari.md", "text": "https://wpnews.pro/news/kiro-as-ai-partner-for-ms-sql-server-optimization-on-net-core-yang-biasa-berhari.txt", "jsonld": "https://wpnews.pro/news/kiro-as-ai-partner-for-ms-sql-server-optimization-on-net-core-yang-biasa-berhari.jsonld"}}