[{"data":1,"prerenderedAt":6215},["ShallowReactive",2],{"navigation_docs":3,"-tu-hoc-database-sql-server-cau-hoi-phong-van":420,"-tu-hoc-database-sql-server-cau-hoi-phong-van-surround":6210},[4,153],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Phỏng vấn .NET","i-lucide-briefcase","\u002Fphong-van","1.phong-van",[10,27,66,111,128],{"title":11,"icon":12,"path":13,"stem":14,"children":15,"page":26},"Tổng quan","i-lucide-compass","\u002Fphong-van\u002Ftong-quan","1.phong-van\u002F1.tong-quan",[16,21],{"title":17,"path":18,"stem":19,"icon":20},"Thị trường HCM","\u002Fphong-van\u002Ftong-quan\u002Fthi-truong","1.phong-van\u002F1.tong-quan\u002F1.thi-truong","i-lucide-trending-up",{"title":22,"path":23,"stem":24,"icon":25},"Lộ trình 7 ngày","\u002Fphong-van\u002Ftong-quan\u002Flo-trinh","1.phong-van\u002F1.tong-quan\u002F2.lo-trinh","i-lucide-calendar-days",false,{"title":22,"icon":25,"path":28,"stem":29,"children":30,"page":26},"\u002Fphong-van\u002Flo-trinh","1.phong-van\u002F2.lo-trinh",[31,36,41,46,51,56,61],{"title":32,"path":33,"stem":34,"icon":35},"Ngày 1 — C# cơ bản","\u002Fphong-van\u002Flo-trinh\u002Fngay-1-csharp-co-ban","1.phong-van\u002F2.lo-trinh\u002F1.ngay-1-csharp-co-ban","i-lucide-1",{"title":37,"path":38,"stem":39,"icon":40},"Ngày 2 — OOP và SOLID","\u002Fphong-van\u002Flo-trinh\u002Fngay-2-oop-solid","1.phong-van\u002F2.lo-trinh\u002F2.ngay-2-oop-solid","i-lucide-2",{"title":42,"path":43,"stem":44,"icon":45},"Ngày 3 — C# nâng cao","\u002Fphong-van\u002Flo-trinh\u002Fngay-3-csharp-nang-cao","1.phong-van\u002F2.lo-trinh\u002F3.ngay-3-csharp-nang-cao","i-lucide-3",{"title":47,"path":48,"stem":49,"icon":50},"Ngày 4 — Database và SQL","\u002Fphong-van\u002Flo-trinh\u002Fngay-4-database-sql","1.phong-van\u002F2.lo-trinh\u002F4.ngay-4-database-sql","i-lucide-4",{"title":52,"path":53,"stem":54,"icon":55},"Ngày 5 — ASP.NET Core và EF Core","\u002Fphong-van\u002Flo-trinh\u002Fngay-5-aspnet-efcore","1.phong-van\u002F2.lo-trinh\u002F5.ngay-5-aspnet-efcore","i-lucide-5",{"title":57,"path":58,"stem":59,"icon":60},"Ngày 6 — DSA coding","\u002Fphong-van\u002Flo-trinh\u002Fngay-6-dsa","1.phong-van\u002F2.lo-trinh\u002F6.ngay-6-dsa","i-lucide-6",{"title":62,"path":63,"stem":64,"icon":65},"Ngày 7 — Mock và HR","\u002Fphong-van\u002Flo-trinh\u002Fngay-7-mock-interview","1.phong-van\u002F2.lo-trinh\u002F7.ngay-7-mock-interview","i-lucide-7",{"title":67,"icon":68,"path":69,"stem":70,"children":71,"page":26},"Ngân hàng câu hỏi","i-lucide-database","\u002Fphong-van\u002Fngan-hang-cau-hoi","1.phong-van\u002F3.ngan-hang-cau-hoi",[72,77,82,87,92,97,102,107],{"title":73,"path":74,"stem":75,"icon":76},"C# (60+ câu)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fcsharp","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F1.csharp","i-lucide-hash",{"title":78,"path":79,"stem":80,"icon":81},"OOP và SOLID (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Foop","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F2.oop","i-lucide-shapes",{"title":83,"path":84,"stem":85,"icon":86},"SQL (40+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fsql","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F3.sql","i-lucide-database-zap",{"title":88,"path":89,"stem":90,"icon":91},"ASP.NET và EF (50+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-ef","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F4.aspnet-ef","i-lucide-server",{"title":93,"path":94,"stem":95,"icon":96},"DSA và Coding (30+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdsa-coding","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F5.dsa-coding","i-lucide-binary",{"title":98,"path":99,"stem":100,"icon":101},"HR và Soft skill (25+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fhr-behavior","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F6.hr-behavior","i-lucide-users",{"title":103,"path":104,"stem":105,"icon":106},"Design Pattern (55+)","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Fdesign-pattern","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F7.design-pattern","i-lucide-puzzle",{"title":108,"path":109,"stem":110,"icon":91},"ASP.NET MVC và Web API","\u002Fphong-van\u002Fngan-hang-cau-hoi\u002Faspnet-mvc-webapi","1.phong-van\u002F3.ngan-hang-cau-hoi\u002F8.aspnet-mvc-webapi",{"title":112,"itle":113,"icon":114,"path":115,"stem":116,"children":117,"page":26},"Tai Lieu","Tài liệu và Cheat sheet","i-lucide-book-marked","\u002Fphong-van\u002Ftai-lieu","1.phong-van\u002F4.tai-lieu",[118,123],{"title":119,"path":120,"stem":121,"icon":122},"Cheat Sheet","\u002Fphong-van\u002Ftai-lieu\u002Fcheatsheet","1.phong-van\u002F4.tai-lieu\u002F1.cheatsheet","i-lucide-clipboard-list",{"title":124,"path":125,"stem":126,"icon":127},"Nguồn tham khảo","\u002Fphong-van\u002Ftai-lieu\u002Fnguon","1.phong-van\u002F4.tai-lieu\u002F2.nguon","i-lucide-link",{"title":129,"icon":130,"path":131,"stem":132,"children":133,"page":26},"Phỏng vấn English","i-lucide-globe","\u002Fphong-van\u002Fenglish-interview","1.phong-van\u002F5.english-interview",[134,138,143,148],{"title":135,"path":136,"stem":137,"icon":130},"Tổng quan English","\u002Fphong-van\u002Fenglish-interview\u002Ftong-quan","1.phong-van\u002F5.english-interview\u002F1.tong-quan",{"title":139,"path":140,"stem":141,"icon":142},"Vocabulary","\u002Fphong-van\u002Fenglish-interview\u002Fvocabulary","1.phong-van\u002F5.english-interview\u002F2.vocabulary","i-lucide-book-a",{"title":144,"path":145,"stem":146,"icon":147},"Technical Q và A (EN)","\u002Fphong-van\u002Fenglish-interview\u002Ftechnical-en","1.phong-van\u002F5.english-interview\u002F3.technical-en","i-lucide-code",{"title":149,"path":150,"stem":151,"icon":152},"Behavioral (EN)","\u002Fphong-van\u002Fenglish-interview\u002Fbehavioral-en","1.phong-van\u002F5.english-interview\u002F4.behavioral-en","i-lucide-message-square-text",{"title":154,"icon":155,"path":156,"stem":157,"children":158},"Tự học","i-lucide-graduation-cap","\u002Ftu-hoc","2.tu-hoc",[159,161,287,310,333,357,384],{"title":154,"path":156,"stem":160,"icon":155},"2.tu-hoc\u002Findex",{"title":162,"icon":68,"path":163,"stem":164,"children":165},"Database","\u002Ftu-hoc\u002Fdatabase","2.tu-hoc\u002F1.database\u002Findex",[166,167,197,222,243,248],{"title":162,"path":163,"stem":164,"icon":68},{"title":168,"icon":91,"path":169,"stem":170,"children":171,"page":26},"SQL Server","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server","2.tu-hoc\u002F1.database\u002F2.sql-server",[172,177,182,187,192],{"title":173,"path":174,"stem":175,"icon":176},"1. Giới thiệu và Cài đặt","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F1.gioi-thieu-cai-dat","i-lucide-play-circle",{"title":178,"path":179,"stem":180,"icon":181},"2. Cú pháp cơ bản","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F2.cu-phap-co-ban","i-lucide-code-2",{"title":183,"path":184,"stem":185,"icon":186},"3. Truy vấn nâng cao","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F3.truy-van-nang-cao","i-lucide-git-merge",{"title":188,"path":189,"stem":190,"icon":191},"4. Đặc thù và Performance","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F4.dac-thu-performance","i-lucide-gauge",{"title":193,"path":194,"stem":195,"icon":196},"5. Q và A phỏng vấn","\u002Ftu-hoc\u002Fdatabase\u002Fsql-server\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F2.sql-server\u002F5.cau-hoi-phong-van","i-lucide-message-circle-question",{"title":198,"icon":199,"path":200,"stem":201,"children":202,"page":26},"PostgreSQL","i-simple-icons-postgresql","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql","2.tu-hoc\u002F1.database\u002F3.postgresql",[203,206,209,212,215,218],{"title":173,"path":204,"stem":205,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":207,"stem":208,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F2.cu-phap-co-ban",{"title":183,"path":210,"stem":211,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F3.truy-van-nang-cao",{"title":188,"path":213,"stem":214,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F4.dac-thu-performance",{"title":193,"path":216,"stem":217,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F5.cau-hoi-phong-van",{"title":219,"path":220,"stem":221,"icon":96},"6. Tích hợp C# và Postgres","\u002Ftu-hoc\u002Fdatabase\u002Fpostgresql\u002Ftich-hop-csharp","2.tu-hoc\u002F1.database\u002F3.postgresql\u002F6.tich-hop-csharp",{"title":223,"icon":224,"path":225,"stem":226,"children":227,"page":26},"MySQL","i-simple-icons-mysql","\u002Ftu-hoc\u002Fdatabase\u002Fmysql","2.tu-hoc\u002F1.database\u002F4.mysql",[228,231,234,237,240],{"title":173,"path":229,"stem":230,"icon":176},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F1.database\u002F4.mysql\u002F1.gioi-thieu-cai-dat",{"title":178,"path":232,"stem":233,"icon":181},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcu-phap-co-ban","2.tu-hoc\u002F1.database\u002F4.mysql\u002F2.cu-phap-co-ban",{"title":183,"path":235,"stem":236,"icon":186},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Ftruy-van-nang-cao","2.tu-hoc\u002F1.database\u002F4.mysql\u002F3.truy-van-nang-cao",{"title":188,"path":238,"stem":239,"icon":191},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fdac-thu-performance","2.tu-hoc\u002F1.database\u002F4.mysql\u002F4.dac-thu-performance",{"title":193,"path":241,"stem":242,"icon":196},"\u002Ftu-hoc\u002Fdatabase\u002Fmysql\u002Fcau-hoi-phong-van","2.tu-hoc\u002F1.database\u002F4.mysql\u002F5.cau-hoi-phong-van",{"title":244,"path":245,"stem":246,"icon":247},"So sánh 3 RDBMS","\u002Ftu-hoc\u002Fdatabase\u002Fso-sanh","2.tu-hoc\u002F1.database\u002F5.so-sanh","i-lucide-columns-3",{"title":249,"path":250,"stem":251,"children":252,"icon":254},"Supabase (BaaS)","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002Findex",[253,255,259,264,269,274,278,283],{"title":249,"path":250,"stem":251,"icon":254},"i-simple-icons-supabase",{"title":256,"path":257,"stem":258,"icon":68},"1. Database","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fdatabase","2.tu-hoc\u002F1.database\u002F6.supabase\u002F1.database",{"title":260,"path":261,"stem":262,"icon":263},"2. Authentication","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fauthentication","2.tu-hoc\u002F1.database\u002F6.supabase\u002F2.authentication","i-lucide-key",{"title":265,"path":266,"stem":267,"icon":268},"3. Storage & Realtime","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fstorage-realtime","2.tu-hoc\u002F1.database\u002F6.supabase\u002F3.storage-realtime","i-lucide-zap",{"title":270,"path":271,"stem":272,"icon":273},"4. Edge Functions & AI","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Ffunctions-ai","2.tu-hoc\u002F1.database\u002F6.supabase\u002F4.functions-ai","i-lucide-brain",{"title":275,"path":276,"stem":277,"icon":181},"5. API & SDKs","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fapi-sdk","2.tu-hoc\u002F1.database\u002F6.supabase\u002F5.api-sdk",{"title":279,"path":280,"stem":281,"icon":282},"6. Platform & Deploy","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Fplatform-deploy","2.tu-hoc\u002F1.database\u002F6.supabase\u002F6.platform-deploy","i-lucide-cloud",{"title":284,"path":285,"stem":286,"icon":196},"7. Interview & Q&A","\u002Ftu-hoc\u002Fdatabase\u002Fsupabase\u002Finterview","2.tu-hoc\u002F1.database\u002F6.supabase\u002F7.interview",{"title":288,"icon":289,"path":290,"stem":291,"children":292},"TypeScript","i-simple-icons-typescript","\u002Ftu-hoc\u002Ftypescript","2.tu-hoc\u002F2.typescript\u002Findex",[293,294,297,301,306],{"title":288,"path":290,"stem":291,"icon":289},{"title":173,"path":295,"stem":296,"icon":176},"\u002Ftu-hoc\u002Ftypescript\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F2.typescript\u002F1.gioi-thieu-cai-dat",{"title":298,"path":299,"stem":300,"icon":81},"2. Type System","\u002Ftu-hoc\u002Ftypescript\u002Ftype-system","2.tu-hoc\u002F2.typescript\u002F2.type-system",{"title":302,"path":303,"stem":304,"icon":305},"3. Advanced types","\u002Ftu-hoc\u002Ftypescript\u002Fadvanced-types","2.tu-hoc\u002F2.typescript\u002F3.advanced-types","i-lucide-braces",{"title":307,"path":308,"stem":309,"icon":196},"4. Q và A phỏng vấn","\u002Ftu-hoc\u002Ftypescript\u002Fcau-hoi-phong-van","2.tu-hoc\u002F2.typescript\u002F4.cau-hoi-phong-van",{"title":311,"icon":81,"path":312,"stem":313,"children":314},"OOP","\u002Ftu-hoc\u002Foop","2.tu-hoc\u002F3.oop\u002Findex",[315,316,321,326,330],{"title":311,"path":312,"stem":313,"icon":81},{"title":317,"path":318,"stem":319,"icon":320},"1. Bốn tính chất","\u002Ftu-hoc\u002Foop\u002F4-tinh-chat","2.tu-hoc\u002F3.oop\u002F1.4-tinh-chat","i-lucide-circle-dot",{"title":322,"path":323,"stem":324,"icon":325},"2. SOLID","\u002Ftu-hoc\u002Foop\u002Fsolid","2.tu-hoc\u002F3.oop\u002F2.solid","i-lucide-shield",{"title":327,"path":328,"stem":329,"icon":106},"3. Design Pattern","\u002Ftu-hoc\u002Foop\u002Fdesign-pattern","2.tu-hoc\u002F3.oop\u002F3.design-pattern",{"title":307,"path":331,"stem":332,"icon":196},"\u002Ftu-hoc\u002Foop\u002Fcau-hoi-phong-van","2.tu-hoc\u002F3.oop\u002F4.cau-hoi-phong-van",{"title":334,"icon":305,"path":335,"stem":336,"children":337},"Generic","\u002Ftu-hoc\u002Fgeneric","2.tu-hoc\u002F4.generic\u002Findex",[338,339,344,349,354],{"title":334,"path":335,"stem":336,"icon":305},{"title":340,"path":341,"stem":342,"icon":343},"1. Khái niệm và cú pháp","\u002Ftu-hoc\u002Fgeneric\u002Fkhai-niem","2.tu-hoc\u002F4.generic\u002F1.khai-niem","i-lucide-book",{"title":345,"path":346,"stem":347,"icon":348},"2. Constraint và Variance","\u002Ftu-hoc\u002Fgeneric\u002Fconstraint-variance","2.tu-hoc\u002F4.generic\u002F2.constraint-variance","i-lucide-filter",{"title":350,"path":351,"stem":352,"icon":353},"3. C# vs TS","\u002Ftu-hoc\u002Fgeneric\u002Fso-sanh","2.tu-hoc\u002F4.generic\u002F3.so-sanh","i-lucide-git-compare",{"title":307,"path":355,"stem":356,"icon":196},"\u002Ftu-hoc\u002Fgeneric\u002Fcau-hoi-phong-van","2.tu-hoc\u002F4.generic\u002F4.cau-hoi-phong-van",{"title":358,"icon":359,"path":360,"stem":361,"children":362},"Nuxt 4","i-simple-icons-nuxt","\u002Ftu-hoc\u002Fnuxt-4","2.tu-hoc\u002F5.nuxt-4\u002Findex",[363,364,367,372,376,379],{"title":358,"path":360,"stem":361,"icon":359},{"title":173,"path":365,"stem":366,"icon":176},"\u002Ftu-hoc\u002Fnuxt-4\u002Fgioi-thieu-cai-dat","2.tu-hoc\u002F5.nuxt-4\u002F1.gioi-thieu-cai-dat",{"title":368,"path":369,"stem":370,"icon":371},"2. Routing và Rendering","\u002Ftu-hoc\u002Fnuxt-4\u002Frouting-rendering","2.tu-hoc\u002F5.nuxt-4\u002F2.routing-rendering","i-lucide-route",{"title":373,"path":374,"stem":375,"icon":91},"3. Data và Server","\u002Ftu-hoc\u002Fnuxt-4\u002Fdata-server","2.tu-hoc\u002F5.nuxt-4\u002F3.data-server",{"title":307,"path":377,"stem":378,"icon":196},"\u002Ftu-hoc\u002Fnuxt-4\u002Fcau-hoi-phong-van","2.tu-hoc\u002F5.nuxt-4\u002F4.cau-hoi-phong-van",{"title":380,"path":381,"stem":382,"icon":383},"5. Practical Todo App","\u002Ftu-hoc\u002Fnuxt-4\u002Fpractical-todo-app","2.tu-hoc\u002F5.nuxt-4\u002F5.practical-todo-app","i-lucide-check-square",{"title":385,"path":386,"stem":387,"children":388,"icon":390},"Tailwind CSS","\u002Ftu-hoc\u002Ftailwindcss","2.tu-hoc\u002F6.tailwindcss\u002Findex",[389,391,396,401,406,411,416],{"title":385,"path":386,"stem":387,"icon":390},"i-simple-icons-tailwindcss",{"title":392,"path":393,"stem":394,"icon":395},"1. Layout & Spacing","\u002Ftu-hoc\u002Ftailwindcss\u002Flayout-spacing","2.tu-hoc\u002F6.tailwindcss\u002F1.layout-spacing","i-lucide-layout",{"title":397,"path":398,"stem":399,"icon":400},"2. Typography & Colors","\u002Ftu-hoc\u002Ftailwindcss\u002Ftypography-colors","2.tu-hoc\u002F6.tailwindcss\u002F2.typography-colors","i-lucide-type",{"title":402,"path":403,"stem":404,"icon":405},"3. Interactive & Effects","\u002Ftu-hoc\u002Ftailwindcss\u002Finteractive-effects","2.tu-hoc\u002F6.tailwindcss\u002F3.interactive-effects","i-lucide-sparkles",{"title":407,"path":408,"stem":409,"icon":410},"4. Responsive & Dark Mode","\u002Ftu-hoc\u002Ftailwindcss\u002Fresponsive-darkmode","2.tu-hoc\u002F6.tailwindcss\u002F4.responsive-darkmode","i-lucide-monitor-smartphone",{"title":412,"path":413,"stem":414,"icon":415},"5. Customization & Theme","\u002Ftu-hoc\u002Ftailwindcss\u002Fcustomization","2.tu-hoc\u002F6.tailwindcss\u002F5.customization","i-lucide-settings-2",{"title":417,"path":418,"stem":419,"icon":181},"6. Practical Projects","\u002Ftu-hoc\u002Ftailwindcss\u002Fpractical-projects","2.tu-hoc\u002F6.tailwindcss\u002F6.practical-projects",{"id":421,"title":422,"body":423,"description":6203,"extension":6204,"links":6205,"meta":6206,"navigation":6207,"path":194,"seo":6208,"stem":195,"__hash__":6209},"docs\u002F2.tu-hoc\u002F1.database\u002F2.sql-server\u002F5.cau-hoi-phong-van.md","Câu hỏi phỏng vấn SQL Server",{"type":424,"value":425,"toc":6075},"minimark",[426,436,441,446,465,473,477,480,488,492,520,524,535,539,561,565,569,583,590,594,607,617,621,635,641,645,656,660,680,690,694,698,752,756,763,767,787,791,798,802,808,812,823,827,853,857,861,965,969,992,996,1002,1006,1009,1024,1028,1032,1043,1047,1059,1063,1082,1086,1092,1096,1099,1103,1117,1121,1124,1135,1139,1166,1170,1201,1205,1212,1216,1221,1225,1228,1232,1235,1244,1248,1252,1255,1259,1267,1271,1274,1278,1289,1293,1296,1305,1309,1312,1321,1324,1328,1331,1339,1345,1349,1352,1356,1380,1384,1388,1391,1395,1401,1405,1416,1420,1426,1430,1436,1440,1443,1447,1453,1457,1461,1472,1476,1479,1483,1497,1500,1504,1517,1521,1529,1532,1536,1539,1553,1566,1570,1594,1598,1601,1605,1608,1612,1616,1619,1711,1714,1718,1724,1729,1813,1818,1857,1860,1864,1870,1941,1946,1966,1969,1973,1979,1984,2042,2047,2180,2189,2193,2199,2204,2212,2217,2497,2500,2504,2575,2580,2619,2624,2667,2670,2674,2680,2795,2801,2805,2809,2824,2900,2905,2990,2993,2997,3004,3086,3091,3144,3147,3151,3154,3159,3246,3251,3304,3318,3323,3398,3402,3408,3413,3447,3452,3485,3490,3538,3545,3549,3553,3556,3632,3637,3761,3766,3814,3825,3829,3901,3906,3940,3947,3951,3956,4020,4025,4068,4073,4107,4125,4129,4133,4138,4143,4161,4195,4198,4202,4208,4213,4227,4295,4356,4359,4363,4366,4376,4424,4434,4500,4519,4532,4536,4543,4548,4601,4606,4674,4731,4734,4738,4742,4749,4846,4910,4913,4917,4924,5036,5041,5084,5087,5091,5096,5131,5136,5219,5222,5226,5230,5375,5382,5386,5389,5395,5400,5477,5483,5487,5624,5630,5634,5673,5678,5787,5793,5797,5930,5945,5949,5957,5960,5985,5997,6018,6022,6045,6049,6063,6071],[427,428,431,435],"callout",{"color":429,"icon":430},"primary","i-lucide-info",[432,433,434],"strong",{},"Cách dùng:"," đọc câu hỏi, tự trả lời ra giấy\u002Fthành tiếng, sau đó so với đáp án. Đừng học thuộc — hiểu cốt lõi, tự diễn đạt.",[437,438,440],"h2",{"id":439},"a-kiến-trúc-cài-đặt","A. Kiến trúc & cài đặt",[442,443,445],"h3",{"id":444},"_1-sql-server-có-những-edition-nào","1. SQL Server có những edition nào?",[447,448,449,452,453,456,457,460,461,464],"p",{},[432,450,451],{},"Developer"," (free, dev only, đầy đủ Enterprise features), ",[432,454,455],{},"Express"," (free, giới hạn 50GB database từ 2025, trước đây 10GB), ",[432,458,459],{},"Standard",", ",[432,462,463],{},"Enterprise",". Azure SQL là phiên bản managed cloud. Học\u002Fdev → Developer hoặc Express.",[427,466,469,472],{"color":467,"icon":468},"warning","i-lucide-star",[432,470,471],{},"Express 2025 tăng từ 10GB lên 50GB"," — đây là thay đổi lớn cho small apps, side projects. Với 50GB, Express có thể chạy production cho nhiều ứng dụng vừa và nhỏ.",[442,474,476],{"id":475},"_2-sql-server-cài-trên-linux-được-không","2. SQL Server cài trên Linux được không?",[447,478,479],{},"Được, từ SQL Server 2017. Docker image chính chủ Microsoft chạy trên Linux container. SQL Server 2025 hỗ trợ Ubuntu 22.04\u002F24.04, RHEL 9, SLES 15. Có thể chạy trên Kubernetes, podman. Hỗ trợ Active Directory authentication trên Linux. Một số feature vẫn Windows-only: SSIS, SSRS, Stretch Database, FileTable.",[427,481,482,483,487],{"color":467,"icon":468},"SQL Server 2025 on Linux gần full feature parity với Windows, bao gồm cả Availability Groups, Machine Learning Services. Container image chính thức có thể pull từ ",[484,485,486],"code",{},"mcr.microsoft.com\u002Fmssql\u002Fserver:2025-latest",".",[442,489,491],{"id":490},"_3-difference-between-sql-and-t-sql","3. Difference between SQL and T-SQL?",[447,493,494,495,460,498,501,502,505,506,460,509,460,512,515,516,519],{},"SQL là chuẩn ANSI. T-SQL (Transact-SQL) là phương ngữ của Microsoft, mở rộng với: variable, control flow (",[484,496,497],{},"IF",[484,499,500],{},"WHILE","), error handling (",[484,503,504],{},"TRY\u002FCATCH","), stored procedure, function, ",[484,507,508],{},"IDENTITY",[484,510,511],{},"OUTPUT",[484,513,514],{},"MERGE",", system function (",[484,517,518],{},"@@",").",[442,521,523],{"id":522},"_4-instance-là-gì","4. Instance là gì?",[447,525,526,527,530,531,534],{},"1 cài đặt SQL Server. 1 server có thể có nhiều instance (",[484,528,529],{},"Default"," và ",[484,532,533],{},"Named","). Mỗi instance có process, RAM, port riêng.",[442,536,538],{"id":537},"_5-ssms-azure-data-studio-sqlcmd-khác-nhau","5. SSMS, Azure Data Studio, sqlcmd — khác nhau?",[540,541,542,549,555],"ul",{},[543,544,545,548],"li",{},[432,546,547],{},"SSMS",": GUI mạnh nhất, Windows-only, miễn phí. Dev .NET chính.",[543,550,551,554],{},[432,552,553],{},"Azure Data Studio",": cross-platform, modern, notebook style.",[543,556,557,560],{},[432,558,559],{},"sqlcmd",": CLI, dùng cho script\u002Fautomation.",[437,562,564],{"id":563},"b-kiểu-dữ-liệu","B. Kiểu dữ liệu",[442,566,568],{"id":567},"_6-varchar-vs-nvarchar-khác-gì","6. VARCHAR vs NVARCHAR khác gì?",[540,570,571,577],{},[543,572,573,576],{},[484,574,575],{},"VARCHAR(n)",": ASCII, 1 byte\u002Fchar.",[543,578,579,582],{},[484,580,581],{},"NVARCHAR(n)",": Unicode (UTF-16), 2 byte\u002Fchar.",[447,584,585,586,589],{},"Cho tiếng Việt\u002FNhật\u002FTrung → bắt buộc ",[484,587,588],{},"NVARCHAR",". Từ 2019, có UTF-8 collation cho phép VARCHAR lưu Unicode tiết kiệm byte hơn.",[442,591,593],{"id":592},"_7-char-vs-varchar","7. CHAR vs VARCHAR?",[540,595,596,602],{},[543,597,598,601],{},[484,599,600],{},"CHAR(n)",": cố định n byte, pad space.",[543,603,604,606],{},[484,605,575],{},": biến đổi, lưu thực + 2 byte length.",[447,608,609,610,613,614,487],{},"Dùng ",[484,611,612],{},"CHAR"," khi length cố định (mã quốc gia 2 ký tự). Còn lại ",[484,615,616],{},"VARCHAR",[442,618,620],{"id":619},"_8-datetime-vs-datetime2","8. DATETIME vs DATETIME2?",[540,622,623,629],{},[543,624,625,628],{},[484,626,627],{},"DATETIME",": 8 bytes, range 1753 → 9999, precision 3.33ms.",[543,630,631,634],{},[484,632,633],{},"DATETIME2(7)",": 6–8 bytes, range 0001 → 9999, precision 100ns.",[447,636,637,638,487],{},"Best practice 2025: ",[432,639,640],{},"luôn dùng DATETIME2",[442,642,644],{"id":643},"_9-vì-sao-tránh-float-cho-tiền","9. Vì sao tránh FLOAT cho tiền?",[447,646,647,648,651,652,655],{},"FLOAT là số gần đúng (IEEE 754). ",[484,649,650],{},"0.1 + 0.2 ≠ 0.3",". Tính tiền → ",[484,653,654],{},"DECIMAL(18, 2)"," chuẩn xác.",[442,657,659],{"id":658},"_10-null-vs-empty-string-vs-0","10. NULL vs '' (empty string) vs 0?",[540,661,662,668,674],{},[543,663,664,667],{},[484,665,666],{},"NULL"," = không xác định, không bằng gì kể cả NULL.",[543,669,670,673],{},[484,671,672],{},"''"," = chuỗi rỗng, có giá trị.",[543,675,676,679],{},[484,677,678],{},"0"," = số 0 cụ thể.",[447,681,682,683,686,687,519],{},"Phải dùng ",[484,684,685],{},"IS NULL"," (không ",[484,688,689],{},"= NULL",[437,691,693],{"id":692},"c-ddl-ràng-buộc","C. DDL & ràng buộc",[442,695,697],{"id":696},"_11-primary-key-vs-unique-key","11. Primary Key vs Unique Key?",[699,700,701,716],"table",{},[702,703,704],"thead",{},[705,706,707,710,713],"tr",{},[708,709],"th",{},[708,711,712],{},"PK",[708,714,715],{},"Unique",[717,718,719,730,741],"tbody",{},[705,720,721,724,727],{},[722,723,666],"td",{},[722,725,726],{},"Không",[722,728,729],{},"1 NULL (SQL Server, khác chuẩn ANSI)",[705,731,732,735,738],{},[722,733,734],{},"Số \u002F bảng",[722,736,737],{},"1",[722,739,740],{},"Nhiều",[705,742,743,746,749],{},[722,744,745],{},"Default index",[722,747,748],{},"Clustered",[722,750,751],{},"Non-clustered",[442,753,755],{"id":754},"_12-foreign-key-để-làm-gì-sql-server-có-tự-index-fk-không","12. Foreign Key để làm gì? SQL Server có tự index FK không?",[447,757,758,759,762],{},"FK đảm bảo referential integrity — con phải có cha. SQL Server ",[432,760,761],{},"không tự"," tạo index trên FK column — nên tạo manual để JOIN nhanh.",[442,764,766],{"id":765},"_13-on-delete-cascade-set-null-no-action-khác-gì","13. ON DELETE CASCADE \u002F SET NULL \u002F NO ACTION khác gì?",[540,768,769,775,781],{},[543,770,771,774],{},[484,772,773],{},"CASCADE",": xoá cha → xoá luôn con.",[543,776,777,780],{},[484,778,779],{},"SET NULL",": xoá cha → FK trong con thành NULL.",[543,782,783,786],{},[484,784,785],{},"NO ACTION",": chặn xoá cha nếu còn con tham chiếu (default).",[442,788,790],{"id":789},"_14-computed-column-và-persisted","14. Computed column và PERSISTED?",[447,792,793,794,797],{},"Cột tính từ cột khác. ",[484,795,796],{},"PERSISTED"," = lưu vật lý, index được. Không PERSISTED = tính khi query.",[442,799,801],{"id":800},"_15-check-constraint","15. CHECK constraint?",[447,803,804,805,487],{},"Ràng buộc business rule trên giá trị: ",[484,806,807],{},"CHECK (Age >= 0 AND Age \u003C= 150)",[442,809,811],{"id":810},"_16-identity-column","16. IDENTITY column?",[447,813,814,815,818,819,822],{},"Auto-increment. ",[484,816,817],{},"IDENTITY(seed, increment)",". Để get value vừa insert: ",[484,820,821],{},"SCOPE_IDENTITY()"," (an toàn nhất, scope hiện tại).",[442,824,826],{"id":825},"_17-identity-vs-scope_identity-vs-ident_current","17. @@IDENTITY vs SCOPE_IDENTITY() vs IDENT_CURRENT()?",[540,828,829,839,847],{},[543,830,831,834,835,838],{},[484,832,833],{},"@@IDENTITY",": identity cuối cùng trong session, ",[432,836,837],{},"kể cả từ trigger"," → có thể sai.",[543,840,841,843,844,487],{},[484,842,821],{},": trong scope hiện tại → ",[432,845,846],{},"dùng cái này",[543,848,849,852],{},[484,850,851],{},"IDENT_CURRENT('table')",": của bảng cụ thể, mọi session.",[437,854,856],{"id":855},"d-dml","D. DML",[442,858,860],{"id":859},"_18-delete-vs-truncate-vs-drop","18. DELETE vs TRUNCATE vs DROP?",[699,862,863,878],{},[702,864,865],{},[705,866,867,869,872,875],{},[708,868],{},[708,870,871],{},"DELETE",[708,873,874],{},"TRUNCATE",[708,876,877],{},"DROP",[717,879,880,893,906,918,929,943,954],{},[705,881,882,885,888,891],{},[722,883,884],{},"Loại",[722,886,887],{},"DML",[722,889,890],{},"DDL",[722,892,890],{},[705,894,895,898,901,904],{},[722,896,897],{},"WHERE",[722,899,900],{},"✅",[722,902,903],{},"❌",[722,905,903],{},[705,907,908,911,913,915],{},[722,909,910],{},"Reset IDENTITY",[722,912,903],{},[722,914,900],{},[722,916,917],{},"N\u002FA",[705,919,920,923,925,927],{},[722,921,922],{},"Trigger",[722,924,900],{},[722,926,903],{},[722,928,917],{},[705,930,931,934,937,940],{},[722,932,933],{},"Tốc độ",[722,935,936],{},"Chậm",[722,938,939],{},"Nhanh",[722,941,942],{},"Nhanh nhất",[705,944,945,948,950,952],{},[722,946,947],{},"Bảng còn?",[722,949,900],{},[722,951,900],{},[722,953,903],{},[705,955,956,959,961,963],{},[722,957,958],{},"Rollback trong tx",[722,960,900],{},[722,962,900],{},[722,964,900],{},[442,966,968],{"id":967},"_19-insert-select","19. INSERT ... SELECT?",[970,971,976],"pre",{"className":972,"code":973,"language":974,"meta":975,"style":975},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","INSERT INTO ArchiveOrders (...)\nSELECT ... FROM Orders WHERE OrderDate \u003C '2025-01-01';\n","sql","",[484,977,978,986],{"__ignoreMap":975},[979,980,983],"span",{"class":981,"line":982},"line",1,[979,984,985],{},"INSERT INTO ArchiveOrders (...)\n",[979,987,989],{"class":981,"line":988},2,[979,990,991],{},"SELECT ... FROM Orders WHERE OrderDate \u003C '2025-01-01';\n",[442,993,995],{"id":994},"_20-merge-dùng-làm-gì-có-gotcha-không","20. MERGE — dùng làm gì? Có gotcha không?",[447,997,998,999,487],{},"Upsert: INSERT nếu chưa có, UPDATE nếu có, có thể DELETE. SQL Server 2025 đã fix hầu hết edge case bugs từng gây tranh cãi — MERGE giờ ổn định hơn nhiều, test kỹ vẫn là best practice. Alternative an toàn: ",[484,1000,1001],{},"IF EXISTS ... UPDATE ... ELSE INSERT",[442,1003,1005],{"id":1004},"_21-output-clause","21. OUTPUT clause?",[447,1007,1008],{},"Trả về row đã insert\u002Fupdate\u002Fdelete trong cùng statement:",[970,1010,1012],{"className":972,"code":1011,"language":974,"meta":975,"style":975},"INSERT INTO Audit OUTPUT INSERTED.* VALUES (...);\nDELETE FROM Orders OUTPUT DELETED.* WHERE ...;\n",[484,1013,1014,1019],{"__ignoreMap":975},[979,1015,1016],{"class":981,"line":982},[979,1017,1018],{},"INSERT INTO Audit OUTPUT INSERTED.* VALUES (...);\n",[979,1020,1021],{"class":981,"line":988},[979,1022,1023],{},"DELETE FROM Orders OUTPUT DELETED.* WHERE ...;\n",[437,1025,1027],{"id":1026},"e-select-join-query","E. SELECT, JOIN, query",[442,1029,1031],{"id":1030},"_22-inner-vs-left-vs-full-join","22. INNER vs LEFT vs FULL JOIN?",[540,1033,1034,1037,1040],{},[543,1035,1036],{},"INNER: chỉ row match cả 2 bảng.",[543,1038,1039],{},"LEFT: tất cả row trái + match phải (NULL nếu không match).",[543,1041,1042],{},"FULL OUTER: tất cả row 2 bên.",[442,1044,1046],{"id":1045},"_23-left-join-where-bị-bẫy-ra-sao","23. LEFT JOIN ... WHERE bị bẫy ra sao?",[447,1048,1049,1050,1052,1053,487],{},"Đặt điều kiện trên bảng phải ở ",[484,1051,897],{}," → loại luôn row có NULL → biến thành INNER. ",[432,1054,1055,1056],{},"Đặt vào ",[484,1057,1058],{},"ON",[442,1060,1062],{"id":1061},"_24-not-in-vs-not-exists","24. NOT IN vs NOT EXISTS?",[447,1064,1065,1068,1069,1072,1073,1076,1077],{},[484,1066,1067],{},"NOT IN"," cho ",[432,1070,1071],{},"kết quả sai"," nếu subquery có NULL. ",[484,1074,1075],{},"NOT EXISTS"," xử lý NULL đúng. ",[432,1078,1079,1080,487],{},"Khuyến nghị: dùng ",[484,1081,1075],{},[442,1083,1085],{"id":1084},"_25-union-vs-union-all-cái-nào-nhanh","25. UNION vs UNION ALL — cái nào nhanh?",[447,1087,1088,1091],{},[484,1089,1090],{},"UNION ALL"," nhanh hơn (không dedupe). Nếu chắc không trùng, dùng UNION ALL.",[442,1093,1095],{"id":1094},"_26-where-vs-having","26. WHERE vs HAVING?",[447,1097,1098],{},"WHERE lọc trước GROUP BY, HAVING lọc sau (dùng được aggregate).",[442,1100,1102],{"id":1101},"_27-top-vs-offsetfetch","27. TOP vs OFFSET\u002FFETCH?",[540,1104,1105,1111],{},[543,1106,1107,1110],{},[484,1108,1109],{},"SELECT TOP N",": lấy N đầu.",[543,1112,1113,1116],{},[484,1114,1115],{},"OFFSET m ROWS FETCH NEXT n ROWS ONLY",": pagination (chuẩn ANSI, từ 2012+).",[442,1118,1120],{"id":1119},"_28-row_number-vs-rank-vs-dense_rank","28. ROW_NUMBER vs RANK vs DENSE_RANK?",[447,1122,1123],{},"Cùng input 100, 100, 90:",[540,1125,1126,1129,1132],{},[543,1127,1128],{},"ROW_NUMBER: 1, 2, 3.",[543,1130,1131],{},"RANK: 1, 1, 3 (skip).",[543,1133,1134],{},"DENSE_RANK: 1, 1, 2 (no skip).",[442,1136,1138],{"id":1137},"_29-lấy-lương-cao-thứ-n","29. Lấy lương cao thứ N?",[970,1140,1142],{"className":972,"code":1141,"language":974,"meta":975,"style":975},"SELECT Salary FROM (\n    SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) rk\n    FROM Employees\n) x WHERE rk = N;\n",[484,1143,1144,1149,1154,1160],{"__ignoreMap":975},[979,1145,1146],{"class":981,"line":982},[979,1147,1148],{},"SELECT Salary FROM (\n",[979,1150,1151],{"class":981,"line":988},[979,1152,1153],{},"    SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) rk\n",[979,1155,1157],{"class":981,"line":1156},3,[979,1158,1159],{},"    FROM Employees\n",[979,1161,1163],{"class":981,"line":1162},4,[979,1164,1165],{},") x WHERE rk = N;\n",[442,1167,1169],{"id":1168},"_30-top-n-per-group","30. Top N per group?",[970,1171,1173],{"className":972,"code":1172,"language":974,"meta":975,"style":975},"WITH Ranked AS (\n    SELECT *, ROW_NUMBER() OVER (PARTITION BY Group ORDER BY Score DESC) rn\n    FROM T\n)\nSELECT * FROM Ranked WHERE rn \u003C= N;\n",[484,1174,1175,1180,1185,1190,1195],{"__ignoreMap":975},[979,1176,1177],{"class":981,"line":982},[979,1178,1179],{},"WITH Ranked AS (\n",[979,1181,1182],{"class":981,"line":988},[979,1183,1184],{},"    SELECT *, ROW_NUMBER() OVER (PARTITION BY Group ORDER BY Score DESC) rn\n",[979,1186,1187],{"class":981,"line":1156},[979,1188,1189],{},"    FROM T\n",[979,1191,1192],{"class":981,"line":1162},[979,1193,1194],{},")\n",[979,1196,1198],{"class":981,"line":1197},5,[979,1199,1200],{},"SELECT * FROM Ranked WHERE rn \u003C= N;\n",[442,1202,1204],{"id":1203},"_31-cte-là-gì-khác-subquery-thế-nào","31. CTE là gì? Khác subquery thế nào?",[447,1206,1207,1208,1211],{},"Common Table Expression — query tạm tên, reference nhiều lần trong cùng statement. Code dễ đọc hơn nested subquery. Hỗ trợ ",[432,1209,1210],{},"recursive"," (tree).",[442,1213,1215],{"id":1214},"_32-recursive-cte-ví-dụ","32. Recursive CTE — ví dụ?",[447,1217,1218,1219,487],{},"Build org chart từ root xuống, traverse comment tree, BOM. Có anchor + recursive part nối bằng ",[484,1220,1090],{},[442,1222,1224],{"id":1223},"_33-khi-nào-dùng-pivot","33. Khi nào dùng PIVOT?",[447,1226,1227],{},"Báo cáo: chuyển row → column. Doanh thu theo tháng, score theo môn học.",[442,1229,1231],{"id":1230},"_34-string_agg-dùng-làm-gì","34. STRING_AGG dùng làm gì?",[447,1233,1234],{},"Gộp string trong group thành 1 string có separator (SQL Server 2017+):",[970,1236,1238],{"className":972,"code":1237,"language":974,"meta":975,"style":975},"STRING_AGG(Name, ', ') WITHIN GROUP (ORDER BY Name)\n",[484,1239,1240],{"__ignoreMap":975},[979,1241,1242],{"class":981,"line":982},[979,1243,1237],{},[437,1245,1247],{"id":1246},"f-index","F. Index",[442,1249,1251],{"id":1250},"_35-index-hoạt-động-ra-sao","35. Index hoạt động ra sao?",[447,1253,1254],{},"B-tree với key sorted. WHERE\u002FJOIN trên cột index → seek O(log n) thay vì O(n). Trade-off: tốn space, slow INSERT\u002FUPDATE.",[442,1256,1258],{"id":1257},"_36-clustered-vs-non-clustered","36. Clustered vs Non-clustered?",[540,1260,1261,1264],{},[543,1262,1263],{},"Clustered: sort vật lý data theo key, 1 cái\u002Fbảng, leaf chứa data.",[543,1265,1266],{},"Non-clustered: B-tree riêng, leaf trỏ về row qua locator.",[442,1268,1270],{"id":1269},"_37-khi-nào-không-nên-tạo-index","37. Khi nào KHÔNG nên tạo index?",[447,1272,1273],{},"Bảng nhỏ, cột thay đổi nhiều, selectivity thấp, bảng heavy write.",[442,1275,1277],{"id":1276},"_38-composite-index-thứ-tự-cột","38. Composite index — thứ tự cột?",[447,1279,1280,1281,1284,1285,1288],{},"Phải theo ",[432,1282,1283],{},"left-most prefix",". ",[484,1286,1287],{},"INDEX(A, B, C)"," dùng được cho A, A+B, A+B+C — không cho B mình hoặc B+C.",[442,1290,1292],{"id":1291},"_39-covering-index","39. Covering index?",[447,1294,1295],{},"Index có thêm cột INCLUDE để query không cần seek về bảng:",[970,1297,1299],{"className":972,"code":1298,"language":974,"meta":975,"style":975},"CREATE INDEX IX ON Orders(CustomerId) INCLUDE (Total, OrderDate);\n",[484,1300,1301],{"__ignoreMap":975},[979,1302,1303],{"class":981,"line":982},[979,1304,1298],{},[442,1306,1308],{"id":1307},"_40-filtered-index","40. Filtered index?",[447,1310,1311],{},"Chỉ index 1 phần dữ liệu:",[970,1313,1315],{"className":972,"code":1314,"language":974,"meta":975,"style":975},"CREATE INDEX IX ON Orders(CustomerId) WHERE Status = 'Active';\n",[484,1316,1317],{"__ignoreMap":975},[979,1318,1319],{"class":981,"line":982},[979,1320,1314],{},[447,1322,1323],{},"Nhỏ hơn, nhanh hơn cho query có cùng filter.",[442,1325,1327],{"id":1326},"_41-sargable-nghĩa-là-gì","41. Sargable nghĩa là gì?",[447,1329,1330],{},"Search-ARGument-able — query mà engine có thể dùng index. Function lên cột → non-sargable → full scan.",[442,1332,1334,1335,1338],{"id":1333},"_42-vì-sao-where-yeardate-2026-chậm","42. Vì sao ",[484,1336,1337],{},"WHERE YEAR(date) = 2026"," chậm?",[447,1340,1341,1342,487],{},"Non-sargable. Sửa: ",[484,1343,1344],{},"WHERE date >= '2026-01-01' AND date \u003C '2027-01-01'",[442,1346,1348],{"id":1347},"_43-key-lookup-là-gì","43. Key Lookup là gì?",[447,1350,1351],{},"Sau index seek (non-clustered), phải nhảy về clustered lấy thêm cột. Dấu hiệu cần covering index.",[442,1353,1355],{"id":1354},"_44-fragmentation-rebuild-vs-reorganize","44. Fragmentation, rebuild vs reorganize?",[540,1357,1358,1361,1368],{},[543,1359,1360],{},"\u003C 5%: bỏ qua.",[543,1362,1363,1364,1367],{},"5–30%: ",[484,1365,1366],{},"REORGANIZE"," (online, nhẹ).",[543,1369,1370],{},[1371,1372,1373],"blockquote",{},[447,1374,1375,1376,1379],{},"30%: ",[484,1377,1378],{},"REBUILD"," (đắt nhưng hết fragment).",[437,1381,1383],{"id":1382},"g-transaction-isolation","G. Transaction & isolation",[442,1385,1387],{"id":1386},"_45-acid-là-gì","45. ACID là gì?",[447,1389,1390],{},"Atomicity, Consistency, Isolation, Durability. Giải thích bằng chuyển khoản: trừ A và cộng B phải atomic; balance không âm (consistency); transaction khác không thấy nháp (isolation); commit xong không mất dù crash (durability).",[442,1392,1394],{"id":1393},"_46-default-isolation-của-sql-server","46. Default isolation của SQL Server?",[447,1396,1397,1400],{},[432,1398,1399],{},"READ COMMITTED"," (block, không MVCC mặc định). Postgres cùng tên nhưng dùng MVCC.",[442,1402,1404],{"id":1403},"_47-3-anomaly-isolation-chống-là-gì","47. 3 anomaly Isolation chống là gì?",[540,1406,1407,1410,1413],{},[543,1408,1409],{},"Dirty read: đọc data chưa commit.",[543,1411,1412],{},"Non-repeatable read: đọc cùng row 2 lần thấy khác.",[543,1414,1415],{},"Phantom read: query range 2 lần thấy thêm\u002Fbớt row.",[442,1417,1419],{"id":1418},"_48-snapshot-isolation-khác-read-committed-chỗ-nào","48. SNAPSHOT isolation khác READ COMMITTED chỗ nào?",[447,1421,1422,1423,487],{},"SNAPSHOT dùng MVCC — đọc snapshot tại thời điểm transaction bắt đầu, không block ghi. Bật bằng ",[484,1424,1425],{},"ALTER DATABASE ... SET ALLOW_SNAPSHOT_ISOLATION ON",[442,1427,1429],{"id":1428},"_49-nolock-hint","49. NOLOCK hint?",[447,1431,1432,1433,487],{},"= READ UNCOMMITTED cho 1 query. Cho phép dirty read. Dùng cho báo cáo chấp nhận sai số. ",[432,1434,1435],{},"Tránh trong nghiệp vụ",[442,1437,1439],{"id":1438},"_50-deadlock-tránh-thế-nào","50. Deadlock — tránh thế nào?",[447,1441,1442],{},"Lock cùng thứ tự, giữ transaction ngắn, isolation thấp hơn nếu được. SQL Server tự pick victim rollback.",[442,1444,1446],{"id":1445},"_51-savepoint","51. Savepoint?",[447,1448,1449,1452],{},[484,1450,1451],{},"SAVE TRANSACTION sp1"," → có thể rollback về savepoint thay vì toàn transaction.",[437,1454,1456],{"id":1455},"h-stored-procedure-function-view","H. Stored procedure, function, view",[442,1458,1460],{"id":1459},"_52-sp-vs-function","52. SP vs Function?",[540,1462,1463,1469],{},[543,1464,1465,1466,487],{},"SP: thực thi logic, trả nhiều resultset, INSERT\u002FUPDATE\u002FDELETE OK, gọi bằng ",[484,1467,1468],{},"EXEC",[543,1470,1471],{},"Function: trả 1 giá trị (scalar) hoặc table, dùng được trong SELECT, không SIDE-EFFECT.",[442,1473,1475],{"id":1474},"_53-view-và-indexed-view","53. View và Indexed View?",[447,1477,1478],{},"View = query lưu sẵn, dùng như table. Indexed View (Materialized View của SQL Server) lưu data vật lý → query nhanh nhưng tốn space + maintenance.",[442,1480,1482],{"id":1481},"_54-trigger-các-loại","54. Trigger các loại?",[540,1484,1485,1491],{},[543,1486,1487,1490],{},[484,1488,1489],{},"AFTER",": sau INSERT\u002FUPDATE\u002FDELETE.",[543,1492,1493,1496],{},[484,1494,1495],{},"INSTEAD OF",": thay thế (cho View, làm view ghi được).",[447,1498,1499],{},"Hạn chế: debug khó, logic ẩn → dùng vừa phải.",[442,1501,1503],{"id":1502},"_55-clr-vs-t-sql","55. CLR vs T-SQL?",[447,1505,1506,1507,460,1510,460,1513,1516],{},"CLR cho phép viết function\u002Fprocedure bằng C#. Dùng cho logic phức tạp khó express bằng T-SQL (complex math, file I\u002FO). Tuy nhiên, SQL Server 2025 đã có native RegEx (",[484,1508,1509],{},"REGEXP_LIKE",[484,1511,1512],{},"REGEXP_REPLACE",[484,1514,1515],{},"REGEXP_SUBSTR",") nên không cần CLR cho regex nữa. Overhead lớn — tránh CLR trong query nóng, ưu tiên T-SQL hoặc batch mode.",[437,1518,1520],{"id":1519},"i-performance","I. Performance",[442,1522,1524,1525,1528],{"id":1523},"_56-vì-sao-tránh-select","56. Vì sao tránh ",[484,1526,1527],{},"SELECT *","?",[447,1530,1531],{},"Lấy cột thừa → băng thông, RAM, phá covering index. Khi bảng thêm cột → query thay đổi hành vi.",[442,1533,1535],{"id":1534},"_57-parameter-sniffing-là-gì-fix-sao","57. Parameter sniffing — là gì? Fix sao?",[447,1537,1538],{},"Plan cache dựa parameter lần đầu → lần sau parameter khác có thể tệ. SQL Server 2025 có 2 cơ chế fix tự động:",[540,1540,1541,1547],{},[543,1542,1543,1546],{},[432,1544,1545],{},"PSPO"," (Parameter Sensitive Plan Optimization): tự động tạo nhiều plan cho cùng 1 query, chọn plan phù hợp theo parameter runtime.",[543,1548,1549,1552],{},[432,1550,1551],{},"OPPO"," (Optional Parameter Plan Optimization): tối ưu cho optional parameter.",[447,1554,1555,1556,460,1559,1562,1563,487],{},"Cách thủ công: ",[484,1557,1558],{},"OPTIMIZE FOR UNKNOWN",[484,1560,1561],{},"RECOMPILE",", hoặc ",[484,1564,1565],{},"OPTION (OPTIMIZE FOR (@p = 'typical_value'))",[442,1567,1569],{"id":1568},"_58-cách-điều-tra-query-chậm","58. Cách điều tra query chậm?",[1571,1572,1573,1579,1582,1585,1588,1591],"ol",{},[543,1574,1575,1576,487],{},"Bật Actual Execution Plan + ",[484,1577,1578],{},"SET STATISTICS IO ON",[543,1580,1581],{},"Tìm operator cost cao (Scan, Sort, Hash Match).",[543,1583,1584],{},"Check thiếu index — SSMS gợi ý.",[543,1586,1587],{},"Update statistics.",[543,1589,1590],{},"Kiểm tra parameter sniffing.",[543,1592,1593],{},"Query Store — xem historical plan regression.",[442,1595,1597],{"id":1596},"_59-khi-nào-dùng-columnstore-index","59. Khi nào dùng Columnstore index?",[447,1599,1600],{},"Bảng analytics rất lớn, query aggregate. Compress ~10x, query 10–100x nhanh hơn. Không hợp single-row lookup.",[442,1602,1604],{"id":1603},"_60-partitioning-khi-nào-cần","60. Partitioning — khi nào cần?",[447,1606,1607],{},"Bảng cực lớn (> 100M row), archive theo thời gian, query luôn filter partition key.",[437,1609,1611],{"id":1610},"j-sql-server-2025-tổng-quan-aivector","J. SQL Server 2025 — Tổng quan & AI\u002FVector",[442,1613,1615],{"id":1614},"_61-có-gì-mới-đáng-chú-ý-ở-sql-server-2025","61. Có gì mới đáng chú ý ở SQL Server 2025?",[447,1617,1618],{},"SQL Server 2025 (phiên bản 17.x) là bản phát hành AI-native, với những feature lớn sau:",[540,1620,1621,1627,1633,1639,1645,1663,1669,1675,1681,1687,1693,1699,1705],{},[543,1622,1623,1626],{},[432,1624,1625],{},"Native VECTOR type",": lưu và query embedding trong DB, không cần vector DB riêng.",[543,1628,1629,1632],{},[432,1630,1631],{},"DiskANN index",": index cho vector search siêu nhanh, tối ưu cho SSD.",[543,1634,1635,1638],{},[432,1636,1637],{},"sp_invoke_external_rest_endpoint",": gọi REST API (OpenAI, Azure AI...) từ T-SQL.",[543,1640,1641,1644],{},[432,1642,1643],{},"JSON first-class type",": validate tự động, compress tốt hơn, index JSON path.",[543,1646,1647,1650,1651,460,1653,460,1655,460,1657,460,1660,487],{},[432,1648,1649],{},"Native RegEx",": ",[484,1652,1509],{},[484,1654,1512],{},[484,1656,1515],{},[484,1658,1659],{},"REGEXP_COUNT",[484,1661,1662],{},"REGEXP_INSTR",[543,1664,1665,1668],{},[432,1666,1667],{},"PSPO \u002F OPPO",": tự động xử lý parameter sniffing, chọn plan tối ưu theo parameter.",[543,1670,1671,1674],{},[432,1672,1673],{},"Optimized Locking",": giảm lock memory, tăng concurrency.",[543,1676,1677,1680],{},[432,1678,1679],{},"CE Feedback",": Cardinality Estimation feedback — tự học và sửa plan sai.",[543,1682,1683,1686],{},[432,1684,1685],{},"Batch Mode cho built-in functions",": STRING_AGG, FIRST_VALUE... chạy batch mode nhanh hơn.",[543,1688,1689,1692],{},[432,1690,1691],{},"TLS 1.3"," default, Entra ID (Azure AD) native integration.",[543,1694,1695,1698],{},[432,1696,1697],{},"Real-time CDC"," sang Azure Event Hubs \u002F Kafka.",[543,1700,1701,1704],{},[432,1702,1703],{},"Express Edition 50GB"," (tăng từ 10GB).",[543,1706,1707,1710],{},[432,1708,1709],{},"Azure Arc"," tích hợp sâu cho hybrid management.",[427,1712,1713],{"color":467,"icon":468},"2025 là bản \"AI-ready\" — bạn có thể xây dựng toàn bộ pipeline RAG (Retrieval-Augmented Generation) ngay trong SQL Server mà không cần stack riêng.",[442,1715,1717],{"id":1716},"_62-vector-type-trong-sql-server-2025-là-gì-dùng-như-thế-nào","62. VECTOR type trong SQL Server 2025 là gì? Dùng như thế nào?",[447,1719,1720,1723],{},[484,1721,1722],{},"VECTOR(n)"," là kiểu dữ liệu native để lưu vector embedding — mảng số thực n chiều dùng trong AI\u002FML. Dùng để semantic search, recommendation, similarity matching ngay trong database, không cần Pinecone\u002FWeaviate\u002FMilvus riêng.",[447,1725,1726],{},[432,1727,1728],{},"Tạo bảng với VECTOR column:",[970,1730,1732],{"className":972,"code":1731,"language":974,"meta":975,"style":975},"CREATE TABLE Documents (\n    Id INT IDENTITY PRIMARY KEY,\n    Title NVARCHAR(500),\n    Content NVARCHAR(MAX),\n    Embedding VECTOR(1536)  -- OpenAI ada-002 embedding\n);\n\n-- Chèn vector\nINSERT INTO Documents (Title, Content, Embedding)\nVALUES (\n    N'Hướng dẫn SQL Server 2025',\n    N'SQL Server 2025 có native VECTOR type...',\n    CAST('[0.0123, -0.0456, 0.0789, ...]' AS VECTOR(1536))\n);\n",[484,1733,1734,1739,1744,1749,1754,1759,1765,1772,1778,1784,1790,1796,1802,1808],{"__ignoreMap":975},[979,1735,1736],{"class":981,"line":982},[979,1737,1738],{},"CREATE TABLE Documents (\n",[979,1740,1741],{"class":981,"line":988},[979,1742,1743],{},"    Id INT IDENTITY PRIMARY KEY,\n",[979,1745,1746],{"class":981,"line":1156},[979,1747,1748],{},"    Title NVARCHAR(500),\n",[979,1750,1751],{"class":981,"line":1162},[979,1752,1753],{},"    Content NVARCHAR(MAX),\n",[979,1755,1756],{"class":981,"line":1197},[979,1757,1758],{},"    Embedding VECTOR(1536)  -- OpenAI ada-002 embedding\n",[979,1760,1762],{"class":981,"line":1761},6,[979,1763,1764],{},");\n",[979,1766,1768],{"class":981,"line":1767},7,[979,1769,1771],{"emptyLinePlaceholder":1770},true,"\n",[979,1773,1775],{"class":981,"line":1774},8,[979,1776,1777],{},"-- Chèn vector\n",[979,1779,1781],{"class":981,"line":1780},9,[979,1782,1783],{},"INSERT INTO Documents (Title, Content, Embedding)\n",[979,1785,1787],{"class":981,"line":1786},10,[979,1788,1789],{},"VALUES (\n",[979,1791,1793],{"class":981,"line":1792},11,[979,1794,1795],{},"    N'Hướng dẫn SQL Server 2025',\n",[979,1797,1799],{"class":981,"line":1798},12,[979,1800,1801],{},"    N'SQL Server 2025 có native VECTOR type...',\n",[979,1803,1805],{"class":981,"line":1804},13,[979,1806,1807],{},"    CAST('[0.0123, -0.0456, 0.0789, ...]' AS VECTOR(1536))\n",[979,1809,1811],{"class":981,"line":1810},14,[979,1812,1764],{},[447,1814,1815],{},[432,1816,1817],{},"Semantic search — tìm document giống nhất:",[970,1819,1821],{"className":972,"code":1820,"language":974,"meta":975,"style":975},"DECLARE @queryEmbedding VECTOR(1536) = CAST('[0.01, -0.04, ...]' AS VECTOR(1536));\n\nSELECT TOP 5\n    Title,\n    VECTOR_DISTANCE('cosine', Embedding, @queryEmbedding) AS Similarity\nFROM Documents\nORDER BY Similarity ASC;  -- cosine distance: càng nhỏ càng giống\n",[484,1822,1823,1828,1832,1837,1842,1847,1852],{"__ignoreMap":975},[979,1824,1825],{"class":981,"line":982},[979,1826,1827],{},"DECLARE @queryEmbedding VECTOR(1536) = CAST('[0.01, -0.04, ...]' AS VECTOR(1536));\n",[979,1829,1830],{"class":981,"line":988},[979,1831,1771],{"emptyLinePlaceholder":1770},[979,1833,1834],{"class":981,"line":1156},[979,1835,1836],{},"SELECT TOP 5\n",[979,1838,1839],{"class":981,"line":1162},[979,1840,1841],{},"    Title,\n",[979,1843,1844],{"class":981,"line":1197},[979,1845,1846],{},"    VECTOR_DISTANCE('cosine', Embedding, @queryEmbedding) AS Similarity\n",[979,1848,1849],{"class":981,"line":1761},[979,1850,1851],{},"FROM Documents\n",[979,1853,1854],{"class":981,"line":1767},[979,1855,1856],{},"ORDER BY Similarity ASC;  -- cosine distance: càng nhỏ càng giống\n",[427,1858,1859],{"color":467,"icon":468},"VECTOR type lưu dưới dạng binary compact — tiết kiệm 50-70% storage so với lưu dạng JSON\u002Fstring. Kết hợp với DiskANN index, truy vấn hàng triệu vector trong vài ms.",[442,1861,1863],{"id":1862},"_63-diskann-index-hoạt-động-ra-sao-khác-hnsw-thế-nào","63. DiskANN index hoạt động ra sao? Khác HNSW thế nào?",[447,1865,1866,1869],{},[432,1867,1868],{},"DiskANN"," (Disk-based Approximate Nearest Neighbor) là thuật toán vector search do Microsoft Research phát triển, được tích hợp native trong SQL Server 2025.",[699,1871,1872,1884],{},[702,1873,1874],{},[705,1875,1876,1879,1881],{},[708,1877,1878],{},"Tiêu chí",[708,1880,1868],{},[708,1882,1883],{},"HNSW (dùng trong pgvector, Weaviate)",[717,1885,1886,1897,1908,1919,1930],{},[705,1887,1888,1891,1894],{},[722,1889,1890],{},"Nơi lưu index",[722,1892,1893],{},"Disk (SSD-optimized)",[722,1895,1896],{},"RAM (in-memory)",[705,1898,1899,1902,1905],{},[722,1900,1901],{},"Dung lượng",[722,1903,1904],{},"Hàng tỷ vector, chỉ cần RAM nhỏ",[722,1906,1907],{},"Bị giới hạn bởi RAM",[705,1909,1910,1913,1916],{},[722,1911,1912],{},"Build index",[722,1914,1915],{},"Nhanh hơn trên dataset lớn",[722,1917,1918],{},"Chậm hơn khi dataset > 10M",[705,1920,1921,1924,1927],{},[722,1922,1923],{},"Query latency",[722,1925,1926],{},"~1-5ms với SSD NVMe",[722,1928,1929],{},"~0.1-1ms (in-memory)",[705,1931,1932,1935,1938],{},[722,1933,1934],{},"Memory footprint",[722,1936,1937],{},"Rất thấp (chỉ cache nóng)",[722,1939,1940],{},"Cao (toàn bộ graph trong RAM)",[447,1942,1943],{},[432,1944,1945],{},"Tạo DiskANN index:",[970,1947,1949],{"className":972,"code":1948,"language":974,"meta":975,"style":975},"CREATE VECTOR INDEX IX_Documents_Embedding\nON Documents (Embedding)\nWITH (DISTANCE_METRIC = 'cosine', INDEX_TYPE = 'DISKANN');\n",[484,1950,1951,1956,1961],{"__ignoreMap":975},[979,1952,1953],{"class":981,"line":982},[979,1954,1955],{},"CREATE VECTOR INDEX IX_Documents_Embedding\n",[979,1957,1958],{"class":981,"line":988},[979,1959,1960],{},"ON Documents (Embedding)\n",[979,1962,1963],{"class":981,"line":1156},[979,1964,1965],{},"WITH (DISTANCE_METRIC = 'cosine', INDEX_TYPE = 'DISKANN');\n",[427,1967,1968],{"color":467,"icon":468},"DiskANN phù hợp cho production workload — bạn có 100M+ vector, RAM server 32GB vẫn query nhanh vì index nằm trên SSD NVMe. HNSW cần RAM đủ chứa toàn bộ graph, với 100M vector 1536-d → cần ~600GB+ RAM.",[442,1970,1972],{"id":1971},"_64-làm-sao-gọi-external-ai-api-từ-t-sql-sp_invoke_external_rest_endpoint","64. Làm sao gọi external AI API từ T-SQL? sp_invoke_external_rest_endpoint",[447,1974,1975,1976,1978],{},"SQL Server 2025 giới thiệu ",[484,1977,1637],{}," — cho phép gọi bất kỳ REST API nào trực tiếp từ T-SQL. Đây là cầu nối để tích hợp AI\u002FML, gọi OpenAI, Azure AI, hoặc bất kỳ service nào.",[447,1980,1981],{},[432,1982,1983],{},"Gọi Azure OpenAI để generate embedding:",[970,1985,1987],{"className":972,"code":1986,"language":974,"meta":975,"style":975},"DECLARE @response NVARCHAR(MAX);\n\nEXEC sp_invoke_external_rest_endpoint\n    @url = 'https:\u002F\u002Fyour-openai.openai.azure.com\u002Fopenai\u002Fdeployments\u002Ftext-embedding-ada-002\u002Fembeddings?api-version=2024-02-01',\n    @method = 'POST',\n    @headers = '{\"api-key\": \"YOUR_API_KEY\", \"Content-Type\": \"application\u002Fjson\"}',\n    @payload = N'{\"input\": \"SQL Server 2025 AI features\"}',\n    @response = @response OUTPUT;\n\n-- Parse embedding từ JSON response (dùng JSON_VALUE với native JSON type)\nSELECT JSON_VALUE(@response, '$.data[0].embedding');\n",[484,1988,1989,1994,1998,2003,2008,2013,2018,2023,2028,2032,2037],{"__ignoreMap":975},[979,1990,1991],{"class":981,"line":982},[979,1992,1993],{},"DECLARE @response NVARCHAR(MAX);\n",[979,1995,1996],{"class":981,"line":988},[979,1997,1771],{"emptyLinePlaceholder":1770},[979,1999,2000],{"class":981,"line":1156},[979,2001,2002],{},"EXEC sp_invoke_external_rest_endpoint\n",[979,2004,2005],{"class":981,"line":1162},[979,2006,2007],{},"    @url = 'https:\u002F\u002Fyour-openai.openai.azure.com\u002Fopenai\u002Fdeployments\u002Ftext-embedding-ada-002\u002Fembeddings?api-version=2024-02-01',\n",[979,2009,2010],{"class":981,"line":1197},[979,2011,2012],{},"    @method = 'POST',\n",[979,2014,2015],{"class":981,"line":1761},[979,2016,2017],{},"    @headers = '{\"api-key\": \"YOUR_API_KEY\", \"Content-Type\": \"application\u002Fjson\"}',\n",[979,2019,2020],{"class":981,"line":1767},[979,2021,2022],{},"    @payload = N'{\"input\": \"SQL Server 2025 AI features\"}',\n",[979,2024,2025],{"class":981,"line":1774},[979,2026,2027],{},"    @response = @response OUTPUT;\n",[979,2029,2030],{"class":981,"line":1780},[979,2031,1771],{"emptyLinePlaceholder":1770},[979,2033,2034],{"class":981,"line":1786},[979,2035,2036],{},"-- Parse embedding từ JSON response (dùng JSON_VALUE với native JSON type)\n",[979,2038,2039],{"class":981,"line":1792},[979,2040,2041],{},"SELECT JSON_VALUE(@response, '$.data[0].embedding');\n",[447,2043,2044],{},[432,2045,2046],{},"Gọi Azure OpenAI Chat Completion ngay trong trigger\u002Fprocedure:",[970,2048,2050],{"className":972,"code":2049,"language":974,"meta":975,"style":975},"-- Tự động summarize khi insert document\nCREATE PROCEDURE SummarizeDocument\n    @content NVARCHAR(MAX),\n    @summary NVARCHAR(MAX) OUTPUT\nAS\nBEGIN\n    DECLARE @response NVARCHAR(MAX);\n    DECLARE @payload NVARCHAR(MAX) = JSON_OBJECT(\n        'messages': JSON_ARRAY(\n            JSON_OBJECT('role': 'system', 'content': 'Summarize in Vietnamese in 2 sentences'),\n            JSON_OBJECT('role': 'user', 'content': @content)\n        ),\n        'max_tokens': 200\n    );\n\n    EXEC sp_invoke_external_rest_endpoint\n        @url = 'https:\u002F\u002Fyour-openai.openai.azure.com\u002Fopenai\u002Fdeployments\u002Fgpt-4\u002Fchat\u002Fcompletions?api-version=2024-02-01',\n        @method = 'POST',\n        @headers = '{\"api-key\": \"YOUR_API_KEY\"}',\n        @payload = @payload,\n        @response = @response OUTPUT;\n\n    SET @summary = JSON_VALUE(@response, '$.choices[0].message.content');\nEND;\n",[484,2051,2052,2057,2062,2067,2072,2077,2082,2087,2092,2097,2102,2107,2112,2117,2122,2127,2133,2139,2145,2151,2157,2163,2168,2174],{"__ignoreMap":975},[979,2053,2054],{"class":981,"line":982},[979,2055,2056],{},"-- Tự động summarize khi insert document\n",[979,2058,2059],{"class":981,"line":988},[979,2060,2061],{},"CREATE PROCEDURE SummarizeDocument\n",[979,2063,2064],{"class":981,"line":1156},[979,2065,2066],{},"    @content NVARCHAR(MAX),\n",[979,2068,2069],{"class":981,"line":1162},[979,2070,2071],{},"    @summary NVARCHAR(MAX) OUTPUT\n",[979,2073,2074],{"class":981,"line":1197},[979,2075,2076],{},"AS\n",[979,2078,2079],{"class":981,"line":1761},[979,2080,2081],{},"BEGIN\n",[979,2083,2084],{"class":981,"line":1767},[979,2085,2086],{},"    DECLARE @response NVARCHAR(MAX);\n",[979,2088,2089],{"class":981,"line":1774},[979,2090,2091],{},"    DECLARE @payload NVARCHAR(MAX) = JSON_OBJECT(\n",[979,2093,2094],{"class":981,"line":1780},[979,2095,2096],{},"        'messages': JSON_ARRAY(\n",[979,2098,2099],{"class":981,"line":1786},[979,2100,2101],{},"            JSON_OBJECT('role': 'system', 'content': 'Summarize in Vietnamese in 2 sentences'),\n",[979,2103,2104],{"class":981,"line":1792},[979,2105,2106],{},"            JSON_OBJECT('role': 'user', 'content': @content)\n",[979,2108,2109],{"class":981,"line":1798},[979,2110,2111],{},"        ),\n",[979,2113,2114],{"class":981,"line":1804},[979,2115,2116],{},"        'max_tokens': 200\n",[979,2118,2119],{"class":981,"line":1810},[979,2120,2121],{},"    );\n",[979,2123,2125],{"class":981,"line":2124},15,[979,2126,1771],{"emptyLinePlaceholder":1770},[979,2128,2130],{"class":981,"line":2129},16,[979,2131,2132],{},"    EXEC sp_invoke_external_rest_endpoint\n",[979,2134,2136],{"class":981,"line":2135},17,[979,2137,2138],{},"        @url = 'https:\u002F\u002Fyour-openai.openai.azure.com\u002Fopenai\u002Fdeployments\u002Fgpt-4\u002Fchat\u002Fcompletions?api-version=2024-02-01',\n",[979,2140,2142],{"class":981,"line":2141},18,[979,2143,2144],{},"        @method = 'POST',\n",[979,2146,2148],{"class":981,"line":2147},19,[979,2149,2150],{},"        @headers = '{\"api-key\": \"YOUR_API_KEY\"}',\n",[979,2152,2154],{"class":981,"line":2153},20,[979,2155,2156],{},"        @payload = @payload,\n",[979,2158,2160],{"class":981,"line":2159},21,[979,2161,2162],{},"        @response = @response OUTPUT;\n",[979,2164,2166],{"class":981,"line":2165},22,[979,2167,1771],{"emptyLinePlaceholder":1770},[979,2169,2171],{"class":981,"line":2170},23,[979,2172,2173],{},"    SET @summary = JSON_VALUE(@response, '$.choices[0].message.content');\n",[979,2175,2177],{"class":981,"line":2176},24,[979,2178,2179],{},"END;\n",[427,2181,2182,2184,2185,2188],{"color":467,"icon":468},[484,2183,1637],{}," cần enable qua ",[484,2186,2187],{},"sp_configure 'external rest endpoint enabled', 1",". Có thể gọi trong trigger, SP, function — nhưng cẩn thận latency và error handling vì gọi mạng.",[442,2190,2192],{"id":2191},"_65-rag-pattern-implement-trong-sql-server-2025-như-thế-nào","65. RAG pattern implement trong SQL Server 2025 như thế nào?",[447,2194,2195,2198],{},[432,2196,2197],{},"RAG"," (Retrieval-Augmented Generation) là pattern phổ biến: tìm document liên quan → gửi kèm vào prompt → LLM trả lời chính xác hơn. Với SQL Server 2025, toàn bộ pipeline chạy trong DB:",[447,2200,2201],{},[432,2202,2203],{},"Kiến trúc RAG trong SQL Server 2025:",[970,2205,2210],{"className":2206,"code":2208,"language":2209},[2207],"language-text","User Question → VECTORIZE (sp_invoke_external_rest_endpoint → embedding API)\n              → VECTOR SEARCH (VECTOR_DISTANCE + DiskANN index → top K documents)\n              → BUILD PROMPT (concat question + retrieved docs)\n              → LLM CALL (sp_invoke_external_rest_endpoint → GPT)\n              → Response\n","text",[484,2211,2208],{"__ignoreMap":975},[447,2213,2214],{},[432,2215,2216],{},"Implement trong 1 SP:",[970,2218,2220],{"className":972,"code":2219,"language":974,"meta":975,"style":975},"CREATE PROCEDURE AskRAG\n    @question NVARCHAR(MAX),\n    @answer NVARCHAR(MAX) OUTPUT\nAS\nBEGIN\n    DECLARE @questionEmbedding VECTOR(1536);\n    DECLARE @context NVARCHAR(MAX) = '';\n    DECLARE @prompt NVARCHAR(MAX);\n    DECLARE @response NVARCHAR(MAX);\n\n    -- Bước 1: Vectorize câu hỏi\n    DECLARE @embedResponse NVARCHAR(MAX);\n    EXEC sp_invoke_external_rest_endpoint\n        @url = 'https:\u002F\u002Fapi.openai.com\u002Fv1\u002Fembeddings',\n        @method = 'POST',\n        @headers = '{\"Authorization\": \"Bearer YOUR_KEY\"}',\n        @payload = JSON_OBJECT('input': @question, 'model': 'text-embedding-ada-002'),\n        @response = @embedResponse OUTPUT;\n\n    SET @questionEmbedding = CAST(\n        JSON_QUERY(@embedResponse, '$.data[0].embedding') AS VECTOR(1536)\n    );\n\n    -- Bước 2: Vector search — tìm 5 document gần nhất\n    SELECT @context = STRING_AGG(Content, CHAR(10) + CHAR(10))\n    FROM (\n        SELECT TOP 5 Content\n        FROM Documents\n        ORDER BY VECTOR_DISTANCE('cosine', Embedding, @questionEmbedding)\n    ) AS relevant;\n\n    -- Bước 3: Build prompt với context\n    SET @prompt = CONCAT(\n        N'Dựa vào các tài liệu sau, trả lời câu hỏi: ',\n        CHAR(10), @question, CHAR(10), CHAR(10),\n        N'Tài liệu tham khảo:', CHAR(10), @context\n    );\n\n    -- Bước 4: Gọi LLM\n    EXEC sp_invoke_external_rest_endpoint\n        @url = 'https:\u002F\u002Fapi.openai.com\u002Fv1\u002Fchat\u002Fcompletions',\n        @method = 'POST',\n        @headers = '{\"Authorization\": \"Bearer YOUR_KEY\"}',\n        @payload = JSON_OBJECT(\n            'model': 'gpt-4',\n            'messages': JSON_ARRAY(\n                JSON_OBJECT('role': 'user', 'content': @prompt)\n            )\n        ),\n        @response = @response OUTPUT;\n\n    SET @answer = JSON_VALUE(@response, '$.choices[0].message.content');\nEND;\n",[484,2221,2222,2227,2232,2237,2241,2245,2250,2255,2260,2264,2268,2273,2278,2282,2287,2291,2296,2301,2306,2310,2315,2320,2324,2328,2333,2339,2345,2351,2357,2363,2369,2374,2380,2386,2392,2398,2404,2409,2414,2420,2425,2431,2436,2441,2447,2453,2459,2465,2471,2476,2481,2486,2492],{"__ignoreMap":975},[979,2223,2224],{"class":981,"line":982},[979,2225,2226],{},"CREATE PROCEDURE AskRAG\n",[979,2228,2229],{"class":981,"line":988},[979,2230,2231],{},"    @question NVARCHAR(MAX),\n",[979,2233,2234],{"class":981,"line":1156},[979,2235,2236],{},"    @answer NVARCHAR(MAX) OUTPUT\n",[979,2238,2239],{"class":981,"line":1162},[979,2240,2076],{},[979,2242,2243],{"class":981,"line":1197},[979,2244,2081],{},[979,2246,2247],{"class":981,"line":1761},[979,2248,2249],{},"    DECLARE @questionEmbedding VECTOR(1536);\n",[979,2251,2252],{"class":981,"line":1767},[979,2253,2254],{},"    DECLARE @context NVARCHAR(MAX) = '';\n",[979,2256,2257],{"class":981,"line":1774},[979,2258,2259],{},"    DECLARE @prompt NVARCHAR(MAX);\n",[979,2261,2262],{"class":981,"line":1780},[979,2263,2086],{},[979,2265,2266],{"class":981,"line":1786},[979,2267,1771],{"emptyLinePlaceholder":1770},[979,2269,2270],{"class":981,"line":1792},[979,2271,2272],{},"    -- Bước 1: Vectorize câu hỏi\n",[979,2274,2275],{"class":981,"line":1798},[979,2276,2277],{},"    DECLARE @embedResponse NVARCHAR(MAX);\n",[979,2279,2280],{"class":981,"line":1804},[979,2281,2132],{},[979,2283,2284],{"class":981,"line":1810},[979,2285,2286],{},"        @url = 'https:\u002F\u002Fapi.openai.com\u002Fv1\u002Fembeddings',\n",[979,2288,2289],{"class":981,"line":2124},[979,2290,2144],{},[979,2292,2293],{"class":981,"line":2129},[979,2294,2295],{},"        @headers = '{\"Authorization\": \"Bearer YOUR_KEY\"}',\n",[979,2297,2298],{"class":981,"line":2135},[979,2299,2300],{},"        @payload = JSON_OBJECT('input': @question, 'model': 'text-embedding-ada-002'),\n",[979,2302,2303],{"class":981,"line":2141},[979,2304,2305],{},"        @response = @embedResponse OUTPUT;\n",[979,2307,2308],{"class":981,"line":2147},[979,2309,1771],{"emptyLinePlaceholder":1770},[979,2311,2312],{"class":981,"line":2153},[979,2313,2314],{},"    SET @questionEmbedding = CAST(\n",[979,2316,2317],{"class":981,"line":2159},[979,2318,2319],{},"        JSON_QUERY(@embedResponse, '$.data[0].embedding') AS VECTOR(1536)\n",[979,2321,2322],{"class":981,"line":2165},[979,2323,2121],{},[979,2325,2326],{"class":981,"line":2170},[979,2327,1771],{"emptyLinePlaceholder":1770},[979,2329,2330],{"class":981,"line":2176},[979,2331,2332],{},"    -- Bước 2: Vector search — tìm 5 document gần nhất\n",[979,2334,2336],{"class":981,"line":2335},25,[979,2337,2338],{},"    SELECT @context = STRING_AGG(Content, CHAR(10) + CHAR(10))\n",[979,2340,2342],{"class":981,"line":2341},26,[979,2343,2344],{},"    FROM (\n",[979,2346,2348],{"class":981,"line":2347},27,[979,2349,2350],{},"        SELECT TOP 5 Content\n",[979,2352,2354],{"class":981,"line":2353},28,[979,2355,2356],{},"        FROM Documents\n",[979,2358,2360],{"class":981,"line":2359},29,[979,2361,2362],{},"        ORDER BY VECTOR_DISTANCE('cosine', Embedding, @questionEmbedding)\n",[979,2364,2366],{"class":981,"line":2365},30,[979,2367,2368],{},"    ) AS relevant;\n",[979,2370,2372],{"class":981,"line":2371},31,[979,2373,1771],{"emptyLinePlaceholder":1770},[979,2375,2377],{"class":981,"line":2376},32,[979,2378,2379],{},"    -- Bước 3: Build prompt với context\n",[979,2381,2383],{"class":981,"line":2382},33,[979,2384,2385],{},"    SET @prompt = CONCAT(\n",[979,2387,2389],{"class":981,"line":2388},34,[979,2390,2391],{},"        N'Dựa vào các tài liệu sau, trả lời câu hỏi: ',\n",[979,2393,2395],{"class":981,"line":2394},35,[979,2396,2397],{},"        CHAR(10), @question, CHAR(10), CHAR(10),\n",[979,2399,2401],{"class":981,"line":2400},36,[979,2402,2403],{},"        N'Tài liệu tham khảo:', CHAR(10), @context\n",[979,2405,2407],{"class":981,"line":2406},37,[979,2408,2121],{},[979,2410,2412],{"class":981,"line":2411},38,[979,2413,1771],{"emptyLinePlaceholder":1770},[979,2415,2417],{"class":981,"line":2416},39,[979,2418,2419],{},"    -- Bước 4: Gọi LLM\n",[979,2421,2423],{"class":981,"line":2422},40,[979,2424,2132],{},[979,2426,2428],{"class":981,"line":2427},41,[979,2429,2430],{},"        @url = 'https:\u002F\u002Fapi.openai.com\u002Fv1\u002Fchat\u002Fcompletions',\n",[979,2432,2434],{"class":981,"line":2433},42,[979,2435,2144],{},[979,2437,2439],{"class":981,"line":2438},43,[979,2440,2295],{},[979,2442,2444],{"class":981,"line":2443},44,[979,2445,2446],{},"        @payload = JSON_OBJECT(\n",[979,2448,2450],{"class":981,"line":2449},45,[979,2451,2452],{},"            'model': 'gpt-4',\n",[979,2454,2456],{"class":981,"line":2455},46,[979,2457,2458],{},"            'messages': JSON_ARRAY(\n",[979,2460,2462],{"class":981,"line":2461},47,[979,2463,2464],{},"                JSON_OBJECT('role': 'user', 'content': @prompt)\n",[979,2466,2468],{"class":981,"line":2467},48,[979,2469,2470],{},"            )\n",[979,2472,2474],{"class":981,"line":2473},49,[979,2475,2111],{},[979,2477,2479],{"class":981,"line":2478},50,[979,2480,2162],{},[979,2482,2484],{"class":981,"line":2483},51,[979,2485,1771],{"emptyLinePlaceholder":1770},[979,2487,2489],{"class":981,"line":2488},52,[979,2490,2491],{},"    SET @answer = JSON_VALUE(@response, '$.choices[0].message.content');\n",[979,2493,2495],{"class":981,"line":2494},53,[979,2496,2179],{},[427,2498,2499],{"color":467,"icon":468},"RAG trong DB giúp: (1) không cần microservice riêng, (2) data không rời khỏi DB, (3) dễ audit\u002Fsecurity, (4) giảm latency vì không gọi qua nhiều service. Phù hợp enterprise có strict data residency.",[442,2501,2503],{"id":2502},"_66-vector_distance-vs-vector_search-khác-nhau-thế-nào","66. VECTOR_DISTANCE vs VECTOR_SEARCH — khác nhau thế nào?",[699,2505,2506,2518],{},[702,2507,2508],{},[705,2509,2510,2512,2515],{},[708,2511],{},[708,2513,2514],{},"VECTOR_DISTANCE",[708,2516,2517],{},"VECTOR_SEARCH",[717,2519,2520,2531,2542,2553,2564],{},[705,2521,2522,2525,2528],{},[722,2523,2524],{},"Mục đích",[722,2526,2527],{},"Tính khoảng cách giữa 2 vector cụ thể",[722,2529,2530],{},"Tìm top K vector gần nhất",[705,2532,2533,2536,2539],{},[722,2534,2535],{},"Dùng index",[722,2537,2538],{},"Không (luôn exact)",[722,2540,2541],{},"Có (tận dụng DiskANN index)",[705,2543,2544,2547,2550],{},[722,2545,2546],{},"Độ chính xác",[722,2548,2549],{},"100% (exact search)",[722,2551,2552],{},"~95-99% (approximate, tùy cấu hình)",[705,2554,2555,2558,2561],{},[722,2556,2557],{},"Performance",[722,2559,2560],{},"Tuyến tính O(n) — quét toàn bộ",[722,2562,2563],{},"O(log n) — dùng index",[705,2565,2566,2569,2572],{},[722,2567,2568],{},"Use case",[722,2570,2571],{},"So sánh 2 document cụ thể",[722,2573,2574],{},"Search trong hàng triệu document",[447,2576,2577],{},[432,2578,2579],{},"VECTOR_DISTANCE — exact comparison:",[970,2581,2583],{"className":972,"code":2582,"language":974,"meta":975,"style":975},"-- So sánh 2 document xem có giống nhau không\nDECLARE @d1 VECTOR(1536), @d2 VECTOR(1536);\nSELECT @d1 = Embedding FROM Documents WHERE Id = 1;\nSELECT @d2 = Embedding FROM Documents WHERE Id = 2;\n\nSELECT VECTOR_DISTANCE('cosine', @d1, @d2) AS SimilarityScore;\n-- Kết quả: 0.0 → 2.0 (cosine): càng gần 0 càng giống\n",[484,2584,2585,2590,2595,2600,2605,2609,2614],{"__ignoreMap":975},[979,2586,2587],{"class":981,"line":982},[979,2588,2589],{},"-- So sánh 2 document xem có giống nhau không\n",[979,2591,2592],{"class":981,"line":988},[979,2593,2594],{},"DECLARE @d1 VECTOR(1536), @d2 VECTOR(1536);\n",[979,2596,2597],{"class":981,"line":1156},[979,2598,2599],{},"SELECT @d1 = Embedding FROM Documents WHERE Id = 1;\n",[979,2601,2602],{"class":981,"line":1162},[979,2603,2604],{},"SELECT @d2 = Embedding FROM Documents WHERE Id = 2;\n",[979,2606,2607],{"class":981,"line":1197},[979,2608,1771],{"emptyLinePlaceholder":1770},[979,2610,2611],{"class":981,"line":1761},[979,2612,2613],{},"SELECT VECTOR_DISTANCE('cosine', @d1, @d2) AS SimilarityScore;\n",[979,2615,2616],{"class":981,"line":1767},[979,2617,2618],{},"-- Kết quả: 0.0 → 2.0 (cosine): càng gần 0 càng giống\n",[447,2620,2621],{},[432,2622,2623],{},"VECTOR_SEARCH — approximate search với index:",[970,2625,2627],{"className":972,"code":2626,"language":974,"meta":975,"style":975},"DECLARE @queryVec VECTOR(1536) = ...;\n\nSELECT TOP 10\n    Id, Title,\n    VECTOR_DISTANCE('cosine', Embedding, @queryVec) AS Score\nFROM Documents\nORDER BY VECTOR_SEARCH('cosine', Embedding, @queryVec, 'IX_Documents_Embedding')\n-- Dùng DiskANN index, nhanh hơn 100-1000x trên dataset lớn\n",[484,2628,2629,2634,2638,2643,2648,2653,2657,2662],{"__ignoreMap":975},[979,2630,2631],{"class":981,"line":982},[979,2632,2633],{},"DECLARE @queryVec VECTOR(1536) = ...;\n",[979,2635,2636],{"class":981,"line":988},[979,2637,1771],{"emptyLinePlaceholder":1770},[979,2639,2640],{"class":981,"line":1156},[979,2641,2642],{},"SELECT TOP 10\n",[979,2644,2645],{"class":981,"line":1162},[979,2646,2647],{},"    Id, Title,\n",[979,2649,2650],{"class":981,"line":1197},[979,2651,2652],{},"    VECTOR_DISTANCE('cosine', Embedding, @queryVec) AS Score\n",[979,2654,2655],{"class":981,"line":1761},[979,2656,1851],{},[979,2658,2659],{"class":981,"line":1767},[979,2660,2661],{},"ORDER BY VECTOR_SEARCH('cosine', Embedding, @queryVec, 'IX_Documents_Embedding')\n",[979,2663,2664],{"class":981,"line":1774},[979,2665,2666],{},"-- Dùng DiskANN index, nhanh hơn 100-1000x trên dataset lớn\n",[427,2668,2669],{"color":467,"icon":468},"VECTOR_SEARCH dùng index DiskANN → approximate, đủ chính xác cho hầu hết use case AI. Chỉ dùng VECTOR_DISTANCE (exact scan) khi cần chính xác 100% hoặc dataset nhỏ \u003C 10K vector.",[442,2671,2673],{"id":2672},"_67-create-external-model-dùng-để-làm-gì","67. CREATE EXTERNAL MODEL dùng để làm gì?",[447,2675,2676,2679],{},[484,2677,2678],{},"CREATE EXTERNAL MODEL"," tạo reference đến AI\u002FML model bên ngoài (Azure ML, ONNX, OpenAI deployment) để sử dụng trong T-SQL prediction:",[970,2681,2683],{"className":972,"code":2682,"language":974,"meta":975,"style":975},"-- Đăng ký Azure OpenAI model\nCREATE EXTERNAL MODEL GPT4o_Model\nWITH (\n    TYPE = 'REST',\n    PROVIDER = 'OPENAI',\n    URL = 'https:\u002F\u002Fyour-openai.openai.azure.com\u002Fopenai\u002Fdeployments\u002Fgpt-4o',\n    AUTHENTICATION = '{\"api-key\": \"YOUR_KEY\"}'\n);\n\n-- Đăng ký ONNX model cho local inference\nCREATE EXTERNAL MODEL SentimentClassifier\nWITH (\n    TYPE = 'ONNX',\n    LOCATION = '\u002Fvar\u002Fopt\u002Fmssql\u002Fmodels\u002Fsentiment_model.onnx',\n    INPUTS = (InputText NVARCHAR(MAX)),\n    OUTPUTS = (Label NVARCHAR(50), Probability FLOAT)\n);\n\n-- Sử dụng model đã đăng ký\nSELECT\n    CommentText,\n    PREDICT(SentimentClassifier, CommentText) AS Sentiment\nFROM Comments;\n",[484,2684,2685,2690,2695,2700,2705,2710,2715,2720,2724,2728,2733,2738,2742,2747,2752,2757,2762,2766,2770,2775,2780,2785,2790],{"__ignoreMap":975},[979,2686,2687],{"class":981,"line":982},[979,2688,2689],{},"-- Đăng ký Azure OpenAI model\n",[979,2691,2692],{"class":981,"line":988},[979,2693,2694],{},"CREATE EXTERNAL MODEL GPT4o_Model\n",[979,2696,2697],{"class":981,"line":1156},[979,2698,2699],{},"WITH (\n",[979,2701,2702],{"class":981,"line":1162},[979,2703,2704],{},"    TYPE = 'REST',\n",[979,2706,2707],{"class":981,"line":1197},[979,2708,2709],{},"    PROVIDER = 'OPENAI',\n",[979,2711,2712],{"class":981,"line":1761},[979,2713,2714],{},"    URL = 'https:\u002F\u002Fyour-openai.openai.azure.com\u002Fopenai\u002Fdeployments\u002Fgpt-4o',\n",[979,2716,2717],{"class":981,"line":1767},[979,2718,2719],{},"    AUTHENTICATION = '{\"api-key\": \"YOUR_KEY\"}'\n",[979,2721,2722],{"class":981,"line":1774},[979,2723,1764],{},[979,2725,2726],{"class":981,"line":1780},[979,2727,1771],{"emptyLinePlaceholder":1770},[979,2729,2730],{"class":981,"line":1786},[979,2731,2732],{},"-- Đăng ký ONNX model cho local inference\n",[979,2734,2735],{"class":981,"line":1792},[979,2736,2737],{},"CREATE EXTERNAL MODEL SentimentClassifier\n",[979,2739,2740],{"class":981,"line":1798},[979,2741,2699],{},[979,2743,2744],{"class":981,"line":1804},[979,2745,2746],{},"    TYPE = 'ONNX',\n",[979,2748,2749],{"class":981,"line":1810},[979,2750,2751],{},"    LOCATION = '\u002Fvar\u002Fopt\u002Fmssql\u002Fmodels\u002Fsentiment_model.onnx',\n",[979,2753,2754],{"class":981,"line":2124},[979,2755,2756],{},"    INPUTS = (InputText NVARCHAR(MAX)),\n",[979,2758,2759],{"class":981,"line":2129},[979,2760,2761],{},"    OUTPUTS = (Label NVARCHAR(50), Probability FLOAT)\n",[979,2763,2764],{"class":981,"line":2135},[979,2765,1764],{},[979,2767,2768],{"class":981,"line":2141},[979,2769,1771],{"emptyLinePlaceholder":1770},[979,2771,2772],{"class":981,"line":2147},[979,2773,2774],{},"-- Sử dụng model đã đăng ký\n",[979,2776,2777],{"class":981,"line":2153},[979,2778,2779],{},"SELECT\n",[979,2781,2782],{"class":981,"line":2159},[979,2783,2784],{},"    CommentText,\n",[979,2786,2787],{"class":981,"line":2165},[979,2788,2789],{},"    PREDICT(SentimentClassifier, CommentText) AS Sentiment\n",[979,2791,2792],{"class":981,"line":2170},[979,2793,2794],{},"FROM Comments;\n",[427,2796,2797,2798,2800],{"color":467,"icon":468},"EXTERNAL MODEL giúp quản lý tập trung model reference, audit trail, và permission. Thay vì hardcode endpoint URL + key trong từng SP, bạn define 1 lần và dùng lại. Thường kết hợp với ",[484,2799,1637],{}," cho REST models.",[437,2802,2804],{"id":2803},"k-sql-server-2025-json","K. SQL Server 2025 — JSON",[442,2806,2808],{"id":2807},"_68-json-type-trong-2025-khác-nvarcharmax-cũ-ra-sao","68. JSON type trong 2025 khác NVARCHAR(MAX) cũ ra sao?",[447,2810,2811,2812,2815,2816,2819,2820,2823],{},"Trước 2025, JSON được lưu dưới dạng ",[484,2813,2814],{},"NVARCHAR(MAX)"," + ",[484,2817,2818],{},"CHECK (ISJSON(col) = 1)",". SQL Server 2025 giới thiệu native ",[484,2821,2822],{},"JSON"," type:",[699,2825,2826,2838],{},[702,2827,2828],{},[705,2829,2830,2832,2835],{},[708,2831],{},[708,2833,2834],{},"NVARCHAR(MAX) + ISJSON",[708,2836,2837],{},"Native JSON (2025)",[717,2839,2840,2854,2865,2876,2886],{},[705,2841,2842,2845,2851],{},[722,2843,2844],{},"Validation",[722,2846,2847,2848],{},"Manual ",[484,2849,2850],{},"CHECK ISJSON()",[722,2852,2853],{},"Tự động, từ chối JSON sai",[705,2855,2856,2859,2862],{},[722,2857,2858],{},"Storage",[722,2860,2861],{},"UTF-16, không compress",[722,2863,2864],{},"Binary format, compress tốt hơn 30-40%",[705,2866,2867,2870,2873],{},[722,2868,2869],{},"Index",[722,2871,2872],{},"Không có native JSON index",[722,2874,2875],{},"JSON index trên path",[705,2877,2878,2880,2883],{},[722,2879,2557],{},[722,2881,2882],{},"Parse mỗi lần query",[722,2884,2885],{},"Pre-parsed, JSON_VALUE nhanh hơn 2-5x",[705,2887,2888,2891,2894],{},[722,2889,2890],{},"Query",[722,2892,2893],{},"JSON_VALUE, JSON_QUERY",[722,2895,2896,2897,2899],{},"Hỗ trợ thêm ",[484,2898,487],{}," dot notation trong path",[447,2901,2902],{},[432,2903,2904],{},"So sánh cũ vs mới:",[970,2906,2908],{"className":972,"code":2907,"language":974,"meta":975,"style":975},"-- Cách cũ (pre-2025)\nCREATE TABLE OldWay (\n    Id INT,\n    Data NVARCHAR(MAX),\n    CONSTRAINT CK_ValidJSON CHECK (ISJSON(Data) = 1)\n);\n\n-- Cách mới (2025)\nCREATE TABLE NewWay (\n    Id INT,\n    Data JSON  -- Native JSON type!\n);\n\n-- Dot notation cho path (mới trong 2025)\nSELECT Data.name, Data.address.city\nFROM NewWay\nWHERE Data.age > 25;\n",[484,2909,2910,2915,2920,2925,2930,2935,2939,2943,2948,2953,2957,2962,2966,2970,2975,2980,2985],{"__ignoreMap":975},[979,2911,2912],{"class":981,"line":982},[979,2913,2914],{},"-- Cách cũ (pre-2025)\n",[979,2916,2917],{"class":981,"line":988},[979,2918,2919],{},"CREATE TABLE OldWay (\n",[979,2921,2922],{"class":981,"line":1156},[979,2923,2924],{},"    Id INT,\n",[979,2926,2927],{"class":981,"line":1162},[979,2928,2929],{},"    Data NVARCHAR(MAX),\n",[979,2931,2932],{"class":981,"line":1197},[979,2933,2934],{},"    CONSTRAINT CK_ValidJSON CHECK (ISJSON(Data) = 1)\n",[979,2936,2937],{"class":981,"line":1761},[979,2938,1764],{},[979,2940,2941],{"class":981,"line":1767},[979,2942,1771],{"emptyLinePlaceholder":1770},[979,2944,2945],{"class":981,"line":1774},[979,2946,2947],{},"-- Cách mới (2025)\n",[979,2949,2950],{"class":981,"line":1780},[979,2951,2952],{},"CREATE TABLE NewWay (\n",[979,2954,2955],{"class":981,"line":1786},[979,2956,2924],{},[979,2958,2959],{"class":981,"line":1792},[979,2960,2961],{},"    Data JSON  -- Native JSON type!\n",[979,2963,2964],{"class":981,"line":1798},[979,2965,1764],{},[979,2967,2968],{"class":981,"line":1804},[979,2969,1771],{"emptyLinePlaceholder":1770},[979,2971,2972],{"class":981,"line":1810},[979,2973,2974],{},"-- Dot notation cho path (mới trong 2025)\n",[979,2976,2977],{"class":981,"line":2124},[979,2978,2979],{},"SELECT Data.name, Data.address.city\n",[979,2981,2982],{"class":981,"line":2129},[979,2983,2984],{},"FROM NewWay\n",[979,2986,2987],{"class":981,"line":2135},[979,2988,2989],{},"WHERE Data.age > 25;\n",[427,2991,2992],{"color":467,"icon":468},"Native JSON type lưu dưới dạng binary OSON (Optimized JSON) — Microsoft's internal format. Parse 1 lần khi insert, query sau dùng pre-parsed structure → query JSON_VALUE nhanh hơn hẳn so với string parsing mỗi lần.",[442,2994,2996],{"id":2995},"_69-json-index-trong-sql-server-2025-hoạt-động-thế-nào","69. JSON index trong SQL Server 2025 hoạt động thế nào?",[447,2998,2999,3000,3003],{},"JSON Index giúp tăng tốc query ",[484,3001,3002],{},"JSON_VALUE"," trên path cụ thể — giống như index trên cột thông thường nhưng cho JSON:",[970,3005,3007],{"className":972,"code":3006,"language":974,"meta":975,"style":975},"-- Tạo bảng với JSON type\nCREATE TABLE Products (\n    Id INT PRIMARY KEY,\n    Details JSON\n);\n\n-- Tạo JSON index trên các field thường query\nCREATE JSON INDEX IX_Product_Category\nON Products (Details)\nON (Details.category, Details.price);\n\n-- Query tận dụng JSON index — seek thay vì scan\nSELECT Id, Details.name\nFROM Products\nWHERE Details.category = N'Điện tử'   -- Dùng index\n  AND Details.price \u003C 5000000;         -- Dùng index\n",[484,3008,3009,3014,3019,3024,3029,3033,3037,3042,3047,3052,3057,3061,3066,3071,3076,3081],{"__ignoreMap":975},[979,3010,3011],{"class":981,"line":982},[979,3012,3013],{},"-- Tạo bảng với JSON type\n",[979,3015,3016],{"class":981,"line":988},[979,3017,3018],{},"CREATE TABLE Products (\n",[979,3020,3021],{"class":981,"line":1156},[979,3022,3023],{},"    Id INT PRIMARY KEY,\n",[979,3025,3026],{"class":981,"line":1162},[979,3027,3028],{},"    Details JSON\n",[979,3030,3031],{"class":981,"line":1197},[979,3032,1764],{},[979,3034,3035],{"class":981,"line":1761},[979,3036,1771],{"emptyLinePlaceholder":1770},[979,3038,3039],{"class":981,"line":1767},[979,3040,3041],{},"-- Tạo JSON index trên các field thường query\n",[979,3043,3044],{"class":981,"line":1774},[979,3045,3046],{},"CREATE JSON INDEX IX_Product_Category\n",[979,3048,3049],{"class":981,"line":1780},[979,3050,3051],{},"ON Products (Details)\n",[979,3053,3054],{"class":981,"line":1786},[979,3055,3056],{},"ON (Details.category, Details.price);\n",[979,3058,3059],{"class":981,"line":1792},[979,3060,1771],{"emptyLinePlaceholder":1770},[979,3062,3063],{"class":981,"line":1798},[979,3064,3065],{},"-- Query tận dụng JSON index — seek thay vì scan\n",[979,3067,3068],{"class":981,"line":1804},[979,3069,3070],{},"SELECT Id, Details.name\n",[979,3072,3073],{"class":981,"line":1810},[979,3074,3075],{},"FROM Products\n",[979,3077,3078],{"class":981,"line":2124},[979,3079,3080],{},"WHERE Details.category = N'Điện tử'   -- Dùng index\n",[979,3082,3083],{"class":981,"line":2129},[979,3084,3085],{},"  AND Details.price \u003C 5000000;         -- Dùng index\n",[447,3087,3088],{},[432,3089,3090],{},"Các loại JSON index:",[970,3092,3094],{"className":972,"code":3093,"language":974,"meta":975,"style":975},"-- Primary JSON index: index mọi path, giống full-text\nCREATE JSON INDEX IX_Primary ON Products (Details);\n\n-- Secondary JSON index: index path cụ thể (nhẹ hơn, nhanh hơn)\nCREATE JSON INDEX IX_Price ON Products (Details)\nON (Details.price);  -- Chỉ index price path\n\n-- Unique JSON index: đảm bảo unique constraint trên JSON field\nCREATE UNIQUE JSON INDEX IX_SKU ON Products (Details)\nON (Details.sku);\n",[484,3095,3096,3101,3106,3110,3115,3120,3125,3129,3134,3139],{"__ignoreMap":975},[979,3097,3098],{"class":981,"line":982},[979,3099,3100],{},"-- Primary JSON index: index mọi path, giống full-text\n",[979,3102,3103],{"class":981,"line":988},[979,3104,3105],{},"CREATE JSON INDEX IX_Primary ON Products (Details);\n",[979,3107,3108],{"class":981,"line":1156},[979,3109,1771],{"emptyLinePlaceholder":1770},[979,3111,3112],{"class":981,"line":1162},[979,3113,3114],{},"-- Secondary JSON index: index path cụ thể (nhẹ hơn, nhanh hơn)\n",[979,3116,3117],{"class":981,"line":1197},[979,3118,3119],{},"CREATE JSON INDEX IX_Price ON Products (Details)\n",[979,3121,3122],{"class":981,"line":1761},[979,3123,3124],{},"ON (Details.price);  -- Chỉ index price path\n",[979,3126,3127],{"class":981,"line":1767},[979,3128,1771],{"emptyLinePlaceholder":1770},[979,3130,3131],{"class":981,"line":1774},[979,3132,3133],{},"-- Unique JSON index: đảm bảo unique constraint trên JSON field\n",[979,3135,3136],{"class":981,"line":1780},[979,3137,3138],{},"CREATE UNIQUE JSON INDEX IX_SKU ON Products (Details)\n",[979,3140,3141],{"class":981,"line":1786},[979,3142,3143],{},"ON (Details.sku);\n",[427,3145,3146],{"color":467,"icon":468},"Không cần index mọi field JSON — chỉ index những path xuất hiện trong WHERE, JOIN, ORDER BY. Mỗi JSON index tốn storage và làm chậm INSERT\u002FUPDATE. Nên dùng secondary JSON index cho field nóng, tránh primary JSON index trừ khi cần.",[442,3148,3150],{"id":3149},"_70-json_arrayagg-json_objectagg-json_contains-dùng-khi-nào","70. JSON_ARRAYAGG, JSON_OBJECTAGG, JSON_CONTAINS dùng khi nào?",[447,3152,3153],{},"SQL Server 2025 bổ sung 3 function JSON mạnh mẽ:",[447,3155,3156],{},[432,3157,3158],{},"JSON_ARRAYAGG — aggregate row thành JSON array:",[970,3160,3162],{"className":972,"code":3161,"language":974,"meta":975,"style":975},"-- Gộp tất cả sản phẩm của mỗi category thành array\nSELECT\n    Category,\n    JSON_ARRAYAGG(\n        JSON_OBJECT('id': Id, 'name': Name, 'price': Price)\n        ORDER BY Price DESC\n    ) AS ProductsArray\nFROM Products\nGROUP BY Category;\n\n\u002F*\nKết quả cho Category = 'Điện tử':\n[\n  {\"id\": 5, \"name\": \"Laptop\", \"price\": 15000000},\n  {\"id\": 3, \"name\": \"Chuột\", \"price\": 500000}\n]\n*\u002F\n",[484,3163,3164,3169,3173,3178,3183,3188,3193,3198,3202,3207,3211,3216,3221,3226,3231,3236,3241],{"__ignoreMap":975},[979,3165,3166],{"class":981,"line":982},[979,3167,3168],{},"-- Gộp tất cả sản phẩm của mỗi category thành array\n",[979,3170,3171],{"class":981,"line":988},[979,3172,2779],{},[979,3174,3175],{"class":981,"line":1156},[979,3176,3177],{},"    Category,\n",[979,3179,3180],{"class":981,"line":1162},[979,3181,3182],{},"    JSON_ARRAYAGG(\n",[979,3184,3185],{"class":981,"line":1197},[979,3186,3187],{},"        JSON_OBJECT('id': Id, 'name': Name, 'price': Price)\n",[979,3189,3190],{"class":981,"line":1761},[979,3191,3192],{},"        ORDER BY Price DESC\n",[979,3194,3195],{"class":981,"line":1767},[979,3196,3197],{},"    ) AS ProductsArray\n",[979,3199,3200],{"class":981,"line":1774},[979,3201,3075],{},[979,3203,3204],{"class":981,"line":1780},[979,3205,3206],{},"GROUP BY Category;\n",[979,3208,3209],{"class":981,"line":1786},[979,3210,1771],{"emptyLinePlaceholder":1770},[979,3212,3213],{"class":981,"line":1792},[979,3214,3215],{},"\u002F*\n",[979,3217,3218],{"class":981,"line":1798},[979,3219,3220],{},"Kết quả cho Category = 'Điện tử':\n",[979,3222,3223],{"class":981,"line":1804},[979,3224,3225],{},"[\n",[979,3227,3228],{"class":981,"line":1810},[979,3229,3230],{},"  {\"id\": 5, \"name\": \"Laptop\", \"price\": 15000000},\n",[979,3232,3233],{"class":981,"line":2124},[979,3234,3235],{},"  {\"id\": 3, \"name\": \"Chuột\", \"price\": 500000}\n",[979,3237,3238],{"class":981,"line":2129},[979,3239,3240],{},"]\n",[979,3242,3243],{"class":981,"line":2135},[979,3244,3245],{},"*\u002F\n",[447,3247,3248],{},[432,3249,3250],{},"JSON_OBJECTAGG — aggregate key-value thành JSON object:",[970,3252,3254],{"className":972,"code":3253,"language":974,"meta":975,"style":975},"-- Tạo object với key = ProductId, value = tên sản phẩm\nSELECT\n    Category,\n    JSON_OBJECTAGG(Id, Name) AS ProductMap\nFROM Products\nGROUP BY Category;\n\n\u002F*\nKết quả:\n{\"1\": \"iPhone\", \"3\": \"Chuột\", \"5\": \"Laptop\"}\n*\u002F\n",[484,3255,3256,3261,3265,3269,3274,3278,3282,3286,3290,3295,3300],{"__ignoreMap":975},[979,3257,3258],{"class":981,"line":982},[979,3259,3260],{},"-- Tạo object với key = ProductId, value = tên sản phẩm\n",[979,3262,3263],{"class":981,"line":988},[979,3264,2779],{},[979,3266,3267],{"class":981,"line":1156},[979,3268,3177],{},[979,3270,3271],{"class":981,"line":1162},[979,3272,3273],{},"    JSON_OBJECTAGG(Id, Name) AS ProductMap\n",[979,3275,3276],{"class":981,"line":1197},[979,3277,3075],{},[979,3279,3280],{"class":981,"line":1761},[979,3281,3206],{},[979,3283,3284],{"class":981,"line":1767},[979,3285,1771],{"emptyLinePlaceholder":1770},[979,3287,3288],{"class":981,"line":1774},[979,3289,3215],{},[979,3291,3292],{"class":981,"line":1780},[979,3293,3294],{},"Kết quả:\n",[979,3296,3297],{"class":981,"line":1786},[979,3298,3299],{},"{\"1\": \"iPhone\", \"3\": \"Chuột\", \"5\": \"Laptop\"}\n",[979,3301,3302],{"class":981,"line":1792},[979,3303,3245],{},[427,3305,3306,3307,3310,3311,530,3314,3317],{"color":429,"icon":430},"Trước 2025, phải dùng ",[484,3308,3309],{},"FOR JSON PATH"," kết hợp subquery phức tạp. ",[484,3312,3313],{},"JSON_ARRAYAGG",[484,3315,3316],{},"JSON_OBJECTAGG"," cho phép aggregate trực tiếp trong GROUP BY — code ngắn hơn, dễ đọc hơn nhiều.",[447,3319,3320],{},[432,3321,3322],{},"JSON_CONTAINS — kiểm tra JSON có chứa value không:",[970,3324,3326],{"className":972,"code":3325,"language":974,"meta":975,"style":975},"-- Kiểm tra array có chứa giá trị\nSELECT *\nFROM Orders\nWHERE JSON_CONTAINS(Tags, '\"VIP\"');  -- Tags = [\"VIP\", \"Urgent\"]\n\n-- Kiểm tra object có chứa key-value\nSELECT *\nFROM Products\nWHERE JSON_CONTAINS(Details, '{\"color\": \"red\"}', '$.attributes');\n\n-- Kiểm tra path tồn tại\nSELECT *\nFROM Configs\nWHERE JSON_CONTAINS(Settings, NULL, '$.features.ai');\n-- TRUE nếu Settings có path $.features.ai dù giá trị là gì\n",[484,3327,3328,3333,3338,3343,3348,3352,3357,3361,3365,3370,3374,3379,3383,3388,3393],{"__ignoreMap":975},[979,3329,3330],{"class":981,"line":982},[979,3331,3332],{},"-- Kiểm tra array có chứa giá trị\n",[979,3334,3335],{"class":981,"line":988},[979,3336,3337],{},"SELECT *\n",[979,3339,3340],{"class":981,"line":1156},[979,3341,3342],{},"FROM Orders\n",[979,3344,3345],{"class":981,"line":1162},[979,3346,3347],{},"WHERE JSON_CONTAINS(Tags, '\"VIP\"');  -- Tags = [\"VIP\", \"Urgent\"]\n",[979,3349,3350],{"class":981,"line":1197},[979,3351,1771],{"emptyLinePlaceholder":1770},[979,3353,3354],{"class":981,"line":1761},[979,3355,3356],{},"-- Kiểm tra object có chứa key-value\n",[979,3358,3359],{"class":981,"line":1767},[979,3360,3337],{},[979,3362,3363],{"class":981,"line":1774},[979,3364,3075],{},[979,3366,3367],{"class":981,"line":1780},[979,3368,3369],{},"WHERE JSON_CONTAINS(Details, '{\"color\": \"red\"}', '$.attributes');\n",[979,3371,3372],{"class":981,"line":1786},[979,3373,1771],{"emptyLinePlaceholder":1770},[979,3375,3376],{"class":981,"line":1792},[979,3377,3378],{},"-- Kiểm tra path tồn tại\n",[979,3380,3381],{"class":981,"line":1798},[979,3382,3337],{},[979,3384,3385],{"class":981,"line":1804},[979,3386,3387],{},"FROM Configs\n",[979,3389,3390],{"class":981,"line":1810},[979,3391,3392],{},"WHERE JSON_CONTAINS(Settings, NULL, '$.features.ai');\n",[979,3394,3395],{"class":981,"line":2124},[979,3396,3397],{},"-- TRUE nếu Settings có path $.features.ai dù giá trị là gì\n",[442,3399,3401],{"id":3400},"_71-json_modify-có-gì-mới-trong-sql-server-2025","71. JSON_MODIFY() có gì mới trong SQL Server 2025?",[447,3403,3404,3407],{},[484,3405,3406],{},"JSON_MODIFY()"," trong 2025 hỗ trợ thêm các thao tác nâng cao và performance tốt hơn với native JSON type:",[447,3409,3410],{},[432,3411,3412],{},"Append vào array:",[970,3414,3416],{"className":972,"code":3415,"language":974,"meta":975,"style":975},"-- Thêm phần tử vào cuối JSON array\nUPDATE Products\nSET Details = JSON_MODIFY(Details, 'append $.tags', N'Bestseller');\n\n-- Trước: {\"tags\": [\"New\", \"Sale\"]}\n-- Sau:   {\"tags\": [\"New\", \"Sale\", \"Bestseller\"]}\n",[484,3417,3418,3423,3428,3433,3437,3442],{"__ignoreMap":975},[979,3419,3420],{"class":981,"line":982},[979,3421,3422],{},"-- Thêm phần tử vào cuối JSON array\n",[979,3424,3425],{"class":981,"line":988},[979,3426,3427],{},"UPDATE Products\n",[979,3429,3430],{"class":981,"line":1156},[979,3431,3432],{},"SET Details = JSON_MODIFY(Details, 'append $.tags', N'Bestseller');\n",[979,3434,3435],{"class":981,"line":1162},[979,3436,1771],{"emptyLinePlaceholder":1770},[979,3438,3439],{"class":981,"line":1197},[979,3440,3441],{},"-- Trước: {\"tags\": [\"New\", \"Sale\"]}\n",[979,3443,3444],{"class":981,"line":1761},[979,3445,3446],{},"-- Sau:   {\"tags\": [\"New\", \"Sale\", \"Bestseller\"]}\n",[447,3448,3449],{},[432,3450,3451],{},"Delete key khỏi object:",[970,3453,3455],{"className":972,"code":3454,"language":974,"meta":975,"style":975},"-- Xóa 1 key khỏi JSON object\nUPDATE Products\nSET Details = JSON_MODIFY(Details, 'delete $.temporaryFlag');\n\n-- Trước: {\"name\": \"Laptop\", \"temporaryFlag\": true, \"price\": 1000}\n-- Sau:   {\"name\": \"Laptop\", \"price\": 1000}\n",[484,3456,3457,3462,3466,3471,3475,3480],{"__ignoreMap":975},[979,3458,3459],{"class":981,"line":982},[979,3460,3461],{},"-- Xóa 1 key khỏi JSON object\n",[979,3463,3464],{"class":981,"line":988},[979,3465,3427],{},[979,3467,3468],{"class":981,"line":1156},[979,3469,3470],{},"SET Details = JSON_MODIFY(Details, 'delete $.temporaryFlag');\n",[979,3472,3473],{"class":981,"line":1162},[979,3474,1771],{"emptyLinePlaceholder":1770},[979,3476,3477],{"class":981,"line":1197},[979,3478,3479],{},"-- Trước: {\"name\": \"Laptop\", \"temporaryFlag\": true, \"price\": 1000}\n",[979,3481,3482],{"class":981,"line":1761},[979,3483,3484],{},"-- Sau:   {\"name\": \"Laptop\", \"price\": 1000}\n",[447,3486,3487],{},[432,3488,3489],{},"Nested modify (nhiều thay đổi trong 1 call):",[970,3491,3493],{"className":972,"code":3492,"language":974,"meta":975,"style":975},"-- 2025 hỗ trợ multiple path operations trong 1 JSON_MODIFY\nUPDATE Products\nSET Details = JSON_MODIFY(\n    Details,\n    'set $.price', 12000000,\n    'set $.discount', 10,\n    'append $.tags', N'Khuyến mãi',\n    'delete $.old_field'\n);\n",[484,3494,3495,3500,3504,3509,3514,3519,3524,3529,3534],{"__ignoreMap":975},[979,3496,3497],{"class":981,"line":982},[979,3498,3499],{},"-- 2025 hỗ trợ multiple path operations trong 1 JSON_MODIFY\n",[979,3501,3502],{"class":981,"line":988},[979,3503,3427],{},[979,3505,3506],{"class":981,"line":1156},[979,3507,3508],{},"SET Details = JSON_MODIFY(\n",[979,3510,3511],{"class":981,"line":1162},[979,3512,3513],{},"    Details,\n",[979,3515,3516],{"class":981,"line":1197},[979,3517,3518],{},"    'set $.price', 12000000,\n",[979,3520,3521],{"class":981,"line":1761},[979,3522,3523],{},"    'set $.discount', 10,\n",[979,3525,3526],{"class":981,"line":1767},[979,3527,3528],{},"    'append $.tags', N'Khuyến mãi',\n",[979,3530,3531],{"class":981,"line":1774},[979,3532,3533],{},"    'delete $.old_field'\n",[979,3535,3536],{"class":981,"line":1780},[979,3537,1764],{},[427,3539,3540,3541,3544],{"color":467,"icon":468},"Với native JSON type (thay vì NVARCHAR), ",[484,3542,3543],{},"JSON_MODIFY"," không cần re-parse toàn bộ JSON string — chỉ modify pre-parsed binary tree → nhanh hơn 3-5x, đặc biệt trên JSON document lớn.",[437,3546,3548],{"id":3547},"l-sql-server-2025-regex","L. SQL Server 2025 — RegEx",[442,3550,3552],{"id":3551},"_72-regexp_like-và-các-function-regex-mới-trong-t-sql-là-gì","72. REGEXP_LIKE và các function RegEx mới trong T-SQL là gì?",[447,3554,3555],{},"SQL Server 2025 giới thiệu 5 function RegEx native — không cần CLR hay LIKE hack nữa:",[699,3557,3558,3570],{},[702,3559,3560],{},[705,3561,3562,3565,3567],{},[708,3563,3564],{},"Function",[708,3566,2524],{},[708,3568,3569],{},"Ví dụ",[717,3571,3572,3584,3596,3608,3620],{},[705,3573,3574,3578,3581],{},[722,3575,3576],{},[484,3577,1509],{},[722,3579,3580],{},"Kiểm tra string khớp pattern",[722,3582,3583],{},"Validate email, phone",[705,3585,3586,3590,3593],{},[722,3587,3588],{},[484,3589,1512],{},[722,3591,3592],{},"Thay thế theo pattern",[722,3594,3595],{},"Clean data, mask sensitive info",[705,3597,3598,3602,3605],{},[722,3599,3600],{},[484,3601,1515],{},[722,3603,3604],{},"Trích xuất substring theo pattern",[722,3606,3607],{},"Lấy domain từ email",[705,3609,3610,3614,3617],{},[722,3611,3612],{},[484,3613,1659],{},[722,3615,3616],{},"Đếm số lần pattern xuất hiện",[722,3618,3619],{},"Đếm từ, đếm tag",[705,3621,3622,3626,3629],{},[722,3623,3624],{},[484,3625,1662],{},[722,3627,3628],{},"Trả về vị trí pattern xuất hiện",[722,3630,3631],{},"Tìm vị trí pattern",[447,3633,3634],{},[432,3635,3636],{},"Ví dụ tổng hợp:",[970,3638,3640],{"className":972,"code":3639,"language":974,"meta":975,"style":975},"DECLARE @text NVARCHAR(500) = N'Liên hệ: email1@example.com, email2@domain.vn. ĐT: 0912-345-678';\n\n-- REGEXP_LIKE: kiểm tra có email không\nSELECT REGEXP_LIKE(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}');\n-- TRUE\n\n-- REGEXP_SUBSTR: lấy email đầu tiên\nSELECT REGEXP_SUBSTR(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}');\n-- 'email1@example.com'\n\n-- REGEXP_REPLACE: mask email thành ***\nSELECT REGEXP_REPLACE(\n    @text,\n    '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}',\n    '***@***.***'\n);\n-- 'Liên hệ: ***@***.***, ***@***.***. ĐT: 0912-345-678'\n\n-- REGEXP_COUNT: đếm số email\nSELECT REGEXP_COUNT(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}');\n-- 2\n\n-- REGEXP_INSTR: vị trí email đầu tiên\nSELECT REGEXP_INSTR(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}');\n-- 10 (vị trí bắt đầu của 'email1@example.com')\n",[484,3641,3642,3647,3651,3656,3661,3666,3670,3675,3680,3685,3689,3694,3699,3704,3709,3714,3718,3723,3727,3732,3737,3742,3746,3751,3756],{"__ignoreMap":975},[979,3643,3644],{"class":981,"line":982},[979,3645,3646],{},"DECLARE @text NVARCHAR(500) = N'Liên hệ: email1@example.com, email2@domain.vn. ĐT: 0912-345-678';\n",[979,3648,3649],{"class":981,"line":988},[979,3650,1771],{"emptyLinePlaceholder":1770},[979,3652,3653],{"class":981,"line":1156},[979,3654,3655],{},"-- REGEXP_LIKE: kiểm tra có email không\n",[979,3657,3658],{"class":981,"line":1162},[979,3659,3660],{},"SELECT REGEXP_LIKE(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}');\n",[979,3662,3663],{"class":981,"line":1197},[979,3664,3665],{},"-- TRUE\n",[979,3667,3668],{"class":981,"line":1761},[979,3669,1771],{"emptyLinePlaceholder":1770},[979,3671,3672],{"class":981,"line":1767},[979,3673,3674],{},"-- REGEXP_SUBSTR: lấy email đầu tiên\n",[979,3676,3677],{"class":981,"line":1774},[979,3678,3679],{},"SELECT REGEXP_SUBSTR(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}');\n",[979,3681,3682],{"class":981,"line":1780},[979,3683,3684],{},"-- 'email1@example.com'\n",[979,3686,3687],{"class":981,"line":1786},[979,3688,1771],{"emptyLinePlaceholder":1770},[979,3690,3691],{"class":981,"line":1792},[979,3692,3693],{},"-- REGEXP_REPLACE: mask email thành ***\n",[979,3695,3696],{"class":981,"line":1798},[979,3697,3698],{},"SELECT REGEXP_REPLACE(\n",[979,3700,3701],{"class":981,"line":1804},[979,3702,3703],{},"    @text,\n",[979,3705,3706],{"class":981,"line":1810},[979,3707,3708],{},"    '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}',\n",[979,3710,3711],{"class":981,"line":2124},[979,3712,3713],{},"    '***@***.***'\n",[979,3715,3716],{"class":981,"line":2129},[979,3717,1764],{},[979,3719,3720],{"class":981,"line":2135},[979,3721,3722],{},"-- 'Liên hệ: ***@***.***, ***@***.***. ĐT: 0912-345-678'\n",[979,3724,3725],{"class":981,"line":2141},[979,3726,1771],{"emptyLinePlaceholder":1770},[979,3728,3729],{"class":981,"line":2147},[979,3730,3731],{},"-- REGEXP_COUNT: đếm số email\n",[979,3733,3734],{"class":981,"line":2153},[979,3735,3736],{},"SELECT REGEXP_COUNT(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}');\n",[979,3738,3739],{"class":981,"line":2159},[979,3740,3741],{},"-- 2\n",[979,3743,3744],{"class":981,"line":2165},[979,3745,1771],{"emptyLinePlaceholder":1770},[979,3747,3748],{"class":981,"line":2170},[979,3749,3750],{},"-- REGEXP_INSTR: vị trí email đầu tiên\n",[979,3752,3753],{"class":981,"line":2176},[979,3754,3755],{},"SELECT REGEXP_INSTR(@text, '[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}');\n",[979,3757,3758],{"class":981,"line":2335},[979,3759,3760],{},"-- 10 (vị trí bắt đầu của 'email1@example.com')\n",[447,3762,3763],{},[432,3764,3765],{},"Validate data với CHECK constraint dùng REGEXP:",[970,3767,3769],{"className":972,"code":3768,"language":974,"meta":975,"style":975},"CREATE TABLE Users (\n    Id INT PRIMARY KEY,\n    Email NVARCHAR(256),\n    Phone NVARCHAR(20),\n    CONSTRAINT CK_ValidEmail\n        CHECK (REGEXP_LIKE(Email, '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$')),\n    CONSTRAINT CK_ValidPhone\n        CHECK (REGEXP_LIKE(Phone, '^0\\d{9,10}$'))\n);\n",[484,3770,3771,3776,3780,3785,3790,3795,3800,3805,3810],{"__ignoreMap":975},[979,3772,3773],{"class":981,"line":982},[979,3774,3775],{},"CREATE TABLE Users (\n",[979,3777,3778],{"class":981,"line":988},[979,3779,3023],{},[979,3781,3782],{"class":981,"line":1156},[979,3783,3784],{},"    Email NVARCHAR(256),\n",[979,3786,3787],{"class":981,"line":1162},[979,3788,3789],{},"    Phone NVARCHAR(20),\n",[979,3791,3792],{"class":981,"line":1197},[979,3793,3794],{},"    CONSTRAINT CK_ValidEmail\n",[979,3796,3797],{"class":981,"line":1761},[979,3798,3799],{},"        CHECK (REGEXP_LIKE(Email, '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$')),\n",[979,3801,3802],{"class":981,"line":1767},[979,3803,3804],{},"    CONSTRAINT CK_ValidPhone\n",[979,3806,3807],{"class":981,"line":1774},[979,3808,3809],{},"        CHECK (REGEXP_LIKE(Phone, '^0\\d{9,10}$'))\n",[979,3811,3812],{"class":981,"line":1780},[979,3813,1764],{},[427,3815,3816,3817,3820,3821,3824],{"color":467,"icon":468},"Pre-2025, RegEx trong SQL Server yêu cầu CLR (C#) hoặc dùng ",[484,3818,3819],{},"PATINDEX","\u002F",[484,3822,3823],{},"LIKE"," hack. Native RegEx 2025: syntax chuẩn POSIX, performance tốt hơn CLR vì chạy trong engine, và được query optimizer hiểu để push-down filter.",[442,3826,3828],{"id":3827},"_73-khi-nào-dùng-regexp-vs-like-performance-comparison","73. Khi nào dùng REGEXP vs LIKE? Performance comparison",[699,3830,3831,3841],{},[702,3832,3833],{},[705,3834,3835,3837,3839],{},[708,3836],{},[708,3838,3823],{},[708,3840,1509],{},[717,3842,3843,3859,3870,3880,3890],{},[705,3844,3845,3848,3856],{},[722,3846,3847],{},"Pattern đơn giản",[722,3849,3850,460,3853],{},[484,3851,3852],{},"LIKE '%abc%'",[484,3854,3855],{},"LIKE 'abc_'",[722,3857,3858],{},"Hơi overkill",[705,3860,3861,3864,3867],{},[722,3862,3863],{},"Pattern phức tạp",[722,3865,3866],{},"Không làm được (alternation, repeat, class)",[722,3868,3869],{},"Dùng REGEXP",[705,3871,3872,3874,3877],{},[722,3873,2557],{},[722,3875,3876],{},"Index seek được nếu prefix cố định",[722,3878,3879],{},"Luôn scan (hiện tại) trừ khi có full-text",[705,3881,3882,3884,3887],{},[722,3883,2568],{},[722,3885,3886],{},"Tìm tên bắt đầu bằng 'Nguyễn'",[722,3888,3889],{},"Validate email, phone, extract data",[705,3891,3892,3895,3898],{},[722,3893,3894],{},"Engine",[722,3896,3897],{},"Simple wildcard matching",[722,3899,3900],{},"Full regex engine (POSIX ERE)",[447,3902,3903],{},[432,3904,3905],{},"Quy tắc chọn:",[970,3907,3909],{"className":972,"code":3908,"language":974,"meta":975,"style":975},"-- Dùng LIKE: pattern đơn giản, prefix cố định → có thể seek index\nSELECT * FROM Customers WHERE Name LIKE N'Nguyễn%';  -- Index seek OK\n\n-- Dùng REGEXP: validate, extract, pattern phức tạp\nSELECT * FROM Customers WHERE REGEXP_LIKE(Email, '^[a-z0-9._%+-]+@gmail\\.com$');\nSELECT REGEXP_REPLACE(Phone, '[^\\d]', '') AS CleanPhone FROM Customers;\n",[484,3910,3911,3916,3921,3925,3930,3935],{"__ignoreMap":975},[979,3912,3913],{"class":981,"line":982},[979,3914,3915],{},"-- Dùng LIKE: pattern đơn giản, prefix cố định → có thể seek index\n",[979,3917,3918],{"class":981,"line":988},[979,3919,3920],{},"SELECT * FROM Customers WHERE Name LIKE N'Nguyễn%';  -- Index seek OK\n",[979,3922,3923],{"class":981,"line":1156},[979,3924,1771],{"emptyLinePlaceholder":1770},[979,3926,3927],{"class":981,"line":1162},[979,3928,3929],{},"-- Dùng REGEXP: validate, extract, pattern phức tạp\n",[979,3931,3932],{"class":981,"line":1197},[979,3933,3934],{},"SELECT * FROM Customers WHERE REGEXP_LIKE(Email, '^[a-z0-9._%+-]+@gmail\\.com$');\n",[979,3936,3937],{"class":981,"line":1761},[979,3938,3939],{},"SELECT REGEXP_REPLACE(Phone, '[^\\d]', '') AS CleanPhone FROM Customers;\n",[427,3941,3942,3943,3946],{"color":467,"icon":468},"REGEXP hiện tại không dùng B-tree index (luôn scan). Với bảng lớn, nếu REGEXP pattern có prefix cố định, cân nhắc: ",[484,3944,3945],{},"WHERE Col LIKE 'prefix%' AND REGEXP_LIKE(Col, 'full_pattern')"," — LIKE filter trước (index seek), REGEXP refine sau. Hoặc dùng full-text index nếu phù hợp.",[442,3948,3950],{"id":3949},"_74-regexp_replace-và-regexp_substr-use-cases-thực-tế","74. REGEXP_REPLACE và REGEXP_SUBSTR — use cases thực tế",[447,3952,3953],{},[432,3954,3955],{},"Clean data hàng loạt:",[970,3957,3959],{"className":972,"code":3958,"language":974,"meta":975,"style":975},"-- Chuẩn hóa số điện thoại: xóa hết non-digit, thêm +84 nếu bắt đầu bằng 0\nUPDATE Customers\nSET Phone = REGEXP_REPLACE(\n    CASE\n        WHEN REGEXP_LIKE(Phone, '^0') THEN '+84' + SUBSTRING(Phone, 2, 20)\n        ELSE Phone\n    END,\n    '[^\\d+]',  -- Xóa mọi thứ không phải số hoặc dấu +\n    ''\n)\nWHERE Phone IS NOT NULL;\n-- '0912.345.678' → '+84912345678'\n",[484,3960,3961,3966,3971,3976,3981,3986,3991,3996,4001,4006,4010,4015],{"__ignoreMap":975},[979,3962,3963],{"class":981,"line":982},[979,3964,3965],{},"-- Chuẩn hóa số điện thoại: xóa hết non-digit, thêm +84 nếu bắt đầu bằng 0\n",[979,3967,3968],{"class":981,"line":988},[979,3969,3970],{},"UPDATE Customers\n",[979,3972,3973],{"class":981,"line":1156},[979,3974,3975],{},"SET Phone = REGEXP_REPLACE(\n",[979,3977,3978],{"class":981,"line":1162},[979,3979,3980],{},"    CASE\n",[979,3982,3983],{"class":981,"line":1197},[979,3984,3985],{},"        WHEN REGEXP_LIKE(Phone, '^0') THEN '+84' + SUBSTRING(Phone, 2, 20)\n",[979,3987,3988],{"class":981,"line":1761},[979,3989,3990],{},"        ELSE Phone\n",[979,3992,3993],{"class":981,"line":1767},[979,3994,3995],{},"    END,\n",[979,3997,3998],{"class":981,"line":1774},[979,3999,4000],{},"    '[^\\d+]',  -- Xóa mọi thứ không phải số hoặc dấu +\n",[979,4002,4003],{"class":981,"line":1780},[979,4004,4005],{},"    ''\n",[979,4007,4008],{"class":981,"line":1786},[979,4009,1194],{},[979,4011,4012],{"class":981,"line":1792},[979,4013,4014],{},"WHERE Phone IS NOT NULL;\n",[979,4016,4017],{"class":981,"line":1798},[979,4018,4019],{},"-- '0912.345.678' → '+84912345678'\n",[447,4021,4022],{},[432,4023,4024],{},"Extract structured data từ text tự do:",[970,4026,4028],{"className":972,"code":4027,"language":974,"meta":975,"style":975},"-- Parse log message: lấy IP, timestamp, status code từ Apache access log\nDECLARE @log NVARCHAR(500) = N'192.168.1.1 - - [08\u002FJul\u002F2026:14:30:00 +0700] \"GET \u002Fapi\u002Fproducts HTTP\u002F1.1\" 200 1234';\n\nSELECT\n    REGEXP_SUBSTR(@log, '^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}') AS IP,\n    REGEXP_SUBSTR(@log, '\\[([^\\]]+)\\]', 1, 1, 1) AS Timestamp,  -- group 1\n    REGEXP_SUBSTR(@log, '\"\\w+ ([^?]+)') AS Endpoint,            -- path sau method\n    REGEXP_SUBSTR(@log, ' (\\d{3}) ') AS StatusCode;\n",[484,4029,4030,4035,4040,4044,4048,4053,4058,4063],{"__ignoreMap":975},[979,4031,4032],{"class":981,"line":982},[979,4033,4034],{},"-- Parse log message: lấy IP, timestamp, status code từ Apache access log\n",[979,4036,4037],{"class":981,"line":988},[979,4038,4039],{},"DECLARE @log NVARCHAR(500) = N'192.168.1.1 - - [08\u002FJul\u002F2026:14:30:00 +0700] \"GET \u002Fapi\u002Fproducts HTTP\u002F1.1\" 200 1234';\n",[979,4041,4042],{"class":981,"line":1156},[979,4043,1771],{"emptyLinePlaceholder":1770},[979,4045,4046],{"class":981,"line":1162},[979,4047,2779],{},[979,4049,4050],{"class":981,"line":1197},[979,4051,4052],{},"    REGEXP_SUBSTR(@log, '^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}') AS IP,\n",[979,4054,4055],{"class":981,"line":1761},[979,4056,4057],{},"    REGEXP_SUBSTR(@log, '\\[([^\\]]+)\\]', 1, 1, 1) AS Timestamp,  -- group 1\n",[979,4059,4060],{"class":981,"line":1767},[979,4061,4062],{},"    REGEXP_SUBSTR(@log, '\"\\w+ ([^?]+)') AS Endpoint,            -- path sau method\n",[979,4064,4065],{"class":981,"line":1774},[979,4066,4067],{},"    REGEXP_SUBSTR(@log, ' (\\d{3}) ') AS StatusCode;\n",[447,4069,4070],{},[432,4071,4072],{},"Data masking trước khi export:",[970,4074,4076],{"className":972,"code":4075,"language":974,"meta":975,"style":975},"-- Mask email và credit card trước khi export ra môi trường test\nSELECT\n    REGEXP_REPLACE(Email, '([^@]+)@', '***@') AS MaskedEmail,\n    REGEXP_REPLACE(CreditCard, '\\d{12}(\\d{4})', '************$1') AS MaskedCC,\n    REGEXP_REPLACE(SSN, '\\d{3}-\\d{2}-(\\d{4})', '***-**-$1') AS MaskedSSN\nFROM SensitiveData;\n",[484,4077,4078,4083,4087,4092,4097,4102],{"__ignoreMap":975},[979,4079,4080],{"class":981,"line":982},[979,4081,4082],{},"-- Mask email và credit card trước khi export ra môi trường test\n",[979,4084,4085],{"class":981,"line":988},[979,4086,2779],{},[979,4088,4089],{"class":981,"line":1156},[979,4090,4091],{},"    REGEXP_REPLACE(Email, '([^@]+)@', '***@') AS MaskedEmail,\n",[979,4093,4094],{"class":981,"line":1162},[979,4095,4096],{},"    REGEXP_REPLACE(CreditCard, '\\d{12}(\\d{4})', '************$1') AS MaskedCC,\n",[979,4098,4099],{"class":981,"line":1197},[979,4100,4101],{},"    REGEXP_REPLACE(SSN, '\\d{3}-\\d{2}-(\\d{4})', '***-**-$1') AS MaskedSSN\n",[979,4103,4104],{"class":981,"line":1761},[979,4105,4106],{},"FROM SensitiveData;\n",[427,4108,4109,4110,460,4113,4116,4117,4120,4121,4124],{"color":467,"icon":468},"REGEXP_REPLACE với capturing group (",[484,4111,4112],{},"$1",[484,4114,4115],{},"$2",") rất mạnh cho data transformation. Nhớ escape backslash trong SQL string: pattern ",[484,4118,4119],{},"\\d"," viết thành ",[484,4122,4123],{},"\\\\d"," hoặc dùng N-prefix literal.",[437,4126,4128],{"id":4127},"m-sql-server-2025-hiệu-năng","M. SQL Server 2025 — Hiệu năng",[442,4130,4132],{"id":4131},"_75-optimized-locking-trong-sql-server-2025-là-gì-tại-sao-quan-trọng","75. Optimized Locking trong SQL Server 2025 là gì? Tại sao quan trọng?",[447,4134,4135,4137],{},[432,4136,1673],{}," là cơ chế quản lý lock mới, giảm đáng kể lock memory và lock escalation. Trước 2025, mỗi row lock tốn ~96 bytes trong lock manager — bảng 10M row update → gần 1GB RAM chỉ cho lock. Optimized Locking giảm xuống còn ~32 bytes\u002Flock bằng cách dùng transaction-local lock hash table.",[447,4139,4140],{},[432,4141,4142],{},"Cơ chế:",[540,4144,4145,4148,4151],{},[543,4146,4147],{},"Lock được lưu ở row-level trong data page (không ở global lock manager).",[543,4149,4150],{},"Chỉ escalate lên global lock manager khi cần cross-transaction conflict.",[543,4152,4153,4154,4157,4158,487],{},"Lock memory tỉ lệ với ",[432,4155,4156],{},"active lock",", không phải ",[432,4159,4160],{},"total locked rows",[970,4162,4164],{"className":972,"code":4163,"language":974,"meta":975,"style":975},"-- Kiểm tra Optimized Locking đã bật chưa\nSELECT name, is_optimized_locking_on\nFROM sys.databases;\n\n-- Bật Optimized Locking (default ON trong 2025)\nALTER DATABASE MyDB SET OPTIMIZED_LOCKING = ON;\n",[484,4165,4166,4171,4176,4181,4185,4190],{"__ignoreMap":975},[979,4167,4168],{"class":981,"line":982},[979,4169,4170],{},"-- Kiểm tra Optimized Locking đã bật chưa\n",[979,4172,4173],{"class":981,"line":988},[979,4174,4175],{},"SELECT name, is_optimized_locking_on\n",[979,4177,4178],{"class":981,"line":1156},[979,4179,4180],{},"FROM sys.databases;\n",[979,4182,4183],{"class":981,"line":1162},[979,4184,1771],{"emptyLinePlaceholder":1770},[979,4186,4187],{"class":981,"line":1197},[979,4188,4189],{},"-- Bật Optimized Locking (default ON trong 2025)\n",[979,4191,4192],{"class":981,"line":1761},[979,4193,4194],{},"ALTER DATABASE MyDB SET OPTIMIZED_LOCKING = ON;\n",[427,4196,4197],{"color":467,"icon":468},"Nếu app của bạn có pattern: xử lý batch lớn (100K+ row update\u002Ftransaction), Optimized Locking giảm lock memory 60-70% và giảm lock escalation → ít bị blocking chain, tăng concurrency đáng kể.",[442,4199,4201],{"id":4200},"_76-ce-feedback-hoạt-động-ra-sao-khác-parameter-sniffing-cũ-thế-nào","76. CE Feedback hoạt động ra sao? Khác parameter sniffing cũ thế nào?",[447,4203,4204,4207],{},[432,4205,4206],{},"Cardinality Estimation (CE) Feedback"," là cơ chế tự động học và sửa sai của query optimizer. Khi optimizer estimate sai số row → plan xấu → CE Feedback ghi nhận và điều chỉnh model cho lần sau.",[447,4209,4210],{},[432,4211,4212],{},"Cách hoạt động:",[1571,4214,4215,4218,4221,4224],{},[543,4216,4217],{},"Query chạy → optimizer estimate 100 row, thực tế 10,000 row.",[543,4219,4220],{},"CE Feedback detect discrepancy (estimate vs actual).",[543,4222,4223],{},"Lần sau, optimizer adjust estimate dựa trên history.",[543,4225,4226],{},"Adjustment persist qua restart (lưu trong Query Store).",[970,4228,4230],{"className":972,"code":4229,"language":974,"meta":975,"style":975},"-- Bật CE Feedback (default ON trong 2025)\nALTER DATABASE SCOPED CONFIGURATION\nSET CE_FEEDBACK = ON;\n\n-- Kiểm tra CE Feedback đã apply cho query nào\nSELECT\n    qt.query_sql_text,\n    p.plan_id,\n    p.ce_feedback_status,\n    p.ce_feedback_last_applied\nFROM sys.query_store_plan p\nJOIN sys.query_store_query qt ON p.query_id = qt.query_id\nWHERE p.ce_feedback_status \u003C> 'None';\n",[484,4231,4232,4237,4242,4247,4251,4256,4260,4265,4270,4275,4280,4285,4290],{"__ignoreMap":975},[979,4233,4234],{"class":981,"line":982},[979,4235,4236],{},"-- Bật CE Feedback (default ON trong 2025)\n",[979,4238,4239],{"class":981,"line":988},[979,4240,4241],{},"ALTER DATABASE SCOPED CONFIGURATION\n",[979,4243,4244],{"class":981,"line":1156},[979,4245,4246],{},"SET CE_FEEDBACK = ON;\n",[979,4248,4249],{"class":981,"line":1162},[979,4250,1771],{"emptyLinePlaceholder":1770},[979,4252,4253],{"class":981,"line":1197},[979,4254,4255],{},"-- Kiểm tra CE Feedback đã apply cho query nào\n",[979,4257,4258],{"class":981,"line":1761},[979,4259,2779],{},[979,4261,4262],{"class":981,"line":1767},[979,4263,4264],{},"    qt.query_sql_text,\n",[979,4266,4267],{"class":981,"line":1774},[979,4268,4269],{},"    p.plan_id,\n",[979,4271,4272],{"class":981,"line":1780},[979,4273,4274],{},"    p.ce_feedback_status,\n",[979,4276,4277],{"class":981,"line":1786},[979,4278,4279],{},"    p.ce_feedback_last_applied\n",[979,4281,4282],{"class":981,"line":1792},[979,4283,4284],{},"FROM sys.query_store_plan p\n",[979,4286,4287],{"class":981,"line":1798},[979,4288,4289],{},"JOIN sys.query_store_query qt ON p.query_id = qt.query_id\n",[979,4291,4292],{"class":981,"line":1804},[979,4293,4294],{},"WHERE p.ce_feedback_status \u003C> 'None';\n",[699,4296,4297,4310],{},[702,4298,4299],{},[705,4300,4301,4304,4307],{},[708,4302,4303],{},"Cơ chế",[708,4305,4306],{},"Parameter Sniffing (cũ)",[708,4308,4309],{},"CE Feedback (2025)",[717,4311,4312,4323,4334,4345],{},[705,4313,4314,4317,4320],{},[722,4315,4316],{},"Nguyên nhân",[722,4318,4319],{},"Plan compile với parameter A, chạy với parameter B",[722,4321,4322],{},"Estimate cardinality sai do statistics cũ hoặc complex predicate",[705,4324,4325,4328,4331],{},[722,4326,4327],{},"Fix",[722,4329,4330],{},"Thủ công (RECOMPILE, hint)",[722,4332,4333],{},"Tự động, persist",[705,4335,4336,4339,4342],{},[722,4337,4338],{},"Scope",[722,4340,4341],{},"1 query, 1 parameter set",[722,4343,4344],{},"Query-wide, mọi parameter",[705,4346,4347,4350,4353],{},[722,4348,4349],{},"Persist",[722,4351,4352],{},"Không (plan recompile thì mất)",[722,4354,4355],{},"Có (lưu trong Query Store)",[427,4357,4358],{"color":467,"icon":468},"CE Feedback + PSPO = bộ đôi fix tự động 2 nguyên nhân chính gây query chậm. CE Feedback sửa estimate sai, PSPO sửa plan không phù hợp parameter. Cả 2 default ON trong 2025 — giảm 70% ticket \"query chạy lúc nhanh lúc chậm\".",[442,4360,4362],{"id":4361},"_77-pspo-và-oppo-giải-quyết-vấn-đề-gì","77. PSPO và OPPO giải quyết vấn đề gì?",[447,4364,4365],{},"Hai cơ chế trong SQL Server 2025 giải quyết parameter sniffing — vấn đề kinh điển khiến plan cache dùng parameter cũ gây query chậm:",[447,4367,4368,4371,4372,4375],{},[432,4369,4370],{},"PSPO (Parameter Sensitive Plan Optimization):","\nTự động tạo ",[432,4373,4374],{},"nhiều plan"," cho cùng 1 query, mỗi plan tối ưu cho 1 range parameter khác nhau. Runtime, engine chọn plan phù hợp dựa trên giá trị thực của parameter.",[970,4377,4379],{"className":972,"code":4378,"language":974,"meta":975,"style":975},"-- Bật PSPO\nALTER DATABASE SCOPED CONFIGURATION\nSET PARAMETER_SENSITIVE_PLAN_OPTIMIZATION = ON;\n\n-- Ví dụ: query này có 2 plan:\n-- Plan A: @Status = 'Active' (80% rows → scan clustered)\n-- Plan B: @Status = 'Pending' (0.1% rows → index seek + key lookup)\nSELECT * FROM Orders WHERE Status = @Status;\n-- PSPO tự tạo cả 2 plan, runtime chọn dựa trên @Status thực tế\n",[484,4380,4381,4386,4390,4395,4399,4404,4409,4414,4419],{"__ignoreMap":975},[979,4382,4383],{"class":981,"line":982},[979,4384,4385],{},"-- Bật PSPO\n",[979,4387,4388],{"class":981,"line":988},[979,4389,4241],{},[979,4391,4392],{"class":981,"line":1156},[979,4393,4394],{},"SET PARAMETER_SENSITIVE_PLAN_OPTIMIZATION = ON;\n",[979,4396,4397],{"class":981,"line":1162},[979,4398,1771],{"emptyLinePlaceholder":1770},[979,4400,4401],{"class":981,"line":1197},[979,4402,4403],{},"-- Ví dụ: query này có 2 plan:\n",[979,4405,4406],{"class":981,"line":1761},[979,4407,4408],{},"-- Plan A: @Status = 'Active' (80% rows → scan clustered)\n",[979,4410,4411],{"class":981,"line":1767},[979,4412,4413],{},"-- Plan B: @Status = 'Pending' (0.1% rows → index seek + key lookup)\n",[979,4415,4416],{"class":981,"line":1774},[979,4417,4418],{},"SELECT * FROM Orders WHERE Status = @Status;\n",[979,4420,4421],{"class":981,"line":1780},[979,4422,4423],{},"-- PSPO tự tạo cả 2 plan, runtime chọn dựa trên @Status thực tế\n",[447,4425,4426,4429,4430,4433],{},[432,4427,4428],{},"OPPO (Optional Parameter Plan Optimization):","\nTối ưu cho query có ",[432,4431,4432],{},"optional parameter"," (NULL = \"lấy tất cả\"):",[970,4435,4437],{"className":972,"code":4436,"language":974,"meta":975,"style":975},"-- Query có optional parameter\nCREATE PROCEDURE SearchOrders\n    @CustomerId INT = NULL,     -- NULL = tất cả khách\n    @Status NVARCHAR(20) = NULL -- NULL = tất cả trạng thái\nAS\nBEGIN\n    SELECT * FROM Orders\n    WHERE (@CustomerId IS NULL OR CustomerId = @CustomerId)\n      AND (@Status IS NULL OR Status = @Status);\nEND;\n\n-- OPPO tự detect và optimize dạng query này,\n-- thay vì 1 plan xấu cho mọi combination\n",[484,4438,4439,4444,4449,4454,4459,4463,4467,4472,4477,4482,4486,4490,4495],{"__ignoreMap":975},[979,4440,4441],{"class":981,"line":982},[979,4442,4443],{},"-- Query có optional parameter\n",[979,4445,4446],{"class":981,"line":988},[979,4447,4448],{},"CREATE PROCEDURE SearchOrders\n",[979,4450,4451],{"class":981,"line":1156},[979,4452,4453],{},"    @CustomerId INT = NULL,     -- NULL = tất cả khách\n",[979,4455,4456],{"class":981,"line":1162},[979,4457,4458],{},"    @Status NVARCHAR(20) = NULL -- NULL = tất cả trạng thái\n",[979,4460,4461],{"class":981,"line":1197},[979,4462,2076],{},[979,4464,4465],{"class":981,"line":1761},[979,4466,2081],{},[979,4468,4469],{"class":981,"line":1767},[979,4470,4471],{},"    SELECT * FROM Orders\n",[979,4473,4474],{"class":981,"line":1774},[979,4475,4476],{},"    WHERE (@CustomerId IS NULL OR CustomerId = @CustomerId)\n",[979,4478,4479],{"class":981,"line":1780},[979,4480,4481],{},"      AND (@Status IS NULL OR Status = @Status);\n",[979,4483,4484],{"class":981,"line":1786},[979,4485,2179],{},[979,4487,4488],{"class":981,"line":1792},[979,4489,1771],{"emptyLinePlaceholder":1770},[979,4491,4492],{"class":981,"line":1798},[979,4493,4494],{},"-- OPPO tự detect và optimize dạng query này,\n",[979,4496,4497],{"class":981,"line":1804},[979,4498,4499],{},"-- thay vì 1 plan xấu cho mọi combination\n",[970,4501,4503],{"className":972,"code":4502,"language":974,"meta":975,"style":975},"-- Bật OPPO\nALTER DATABASE SCOPED CONFIGURATION\nSET OPTIONAL_PARAMETER_PLAN_OPTIMIZATION = ON;\n",[484,4504,4505,4510,4514],{"__ignoreMap":975},[979,4506,4507],{"class":981,"line":982},[979,4508,4509],{},"-- Bật OPPO\n",[979,4511,4512],{"class":981,"line":988},[979,4513,4241],{},[979,4515,4516],{"class":981,"line":1156},[979,4517,4518],{},"SET OPTIONAL_PARAMETER_PLAN_OPTIMIZATION = ON;\n",[427,4520,4521,4524,4525,4528,4529,4531],{"color":467,"icon":468},[432,4522,4523],{},"Phân biệt nhanh:"," PSPO = nhiều plan cho cùng query dựa trên parameter selectivity. OPPO = optimize query có ",[484,4526,4527],{},"@p IS NULL OR col = @p"," pattern. Cả 2 đều là adaptive optimization, không cần ",[484,4530,1561],{}," hint.",[442,4533,4535],{"id":4534},"_78-batch-mode-cho-built-in-functions-hiệu-suất-tăng-bao-nhiêu","78. Batch Mode cho built-in functions — hiệu suất tăng bao nhiêu?",[447,4537,4538,4539,4542],{},"SQL Server 2025 mở rộng ",[432,4540,4541],{},"Batch Mode on Rowstore"," — cho phép một số built-in functions chạy dưới dạng batch processing (xử lý 900 row\u002Flô) thay vì row-by-row:",[447,4544,4545],{},[432,4546,4547],{},"Function được hưởng lợi:",[540,4549,4550,4555,4563,4571,4579,4587],{},[543,4551,4552],{},[484,4553,4554],{},"STRING_AGG",[543,4556,4557,460,4560],{},[484,4558,4559],{},"FIRST_VALUE",[484,4561,4562],{},"LAST_VALUE",[543,4564,4565,460,4568],{},[484,4566,4567],{},"LAG",[484,4569,4570],{},"LEAD",[543,4572,4573,460,4576],{},[484,4574,4575],{},"PERCENTILE_CONT",[484,4577,4578],{},"PERCENTILE_DISC",[543,4580,4581,460,4584],{},[484,4582,4583],{},"APPROX_PERCENTILE_CONT",[484,4585,4586],{},"APPROX_PERCENTILE_DISC",[543,4588,4589,460,4592,460,4595,460,4598],{},[484,4590,4591],{},"ROW_NUMBER",[484,4593,4594],{},"RANK",[484,4596,4597],{},"DENSE_RANK",[484,4599,4600],{},"NTILE",[447,4602,4603],{},[432,4604,4605],{},"Performance impact (theo Microsoft benchmark):",[699,4607,4608,4624],{},[702,4609,4610],{},[705,4611,4612,4615,4618,4621],{},[708,4613,4614],{},"Operation",[708,4616,4617],{},"Row Mode",[708,4619,4620],{},"Batch Mode (2025)",[708,4622,4623],{},"Speedup",[717,4625,4626,4642,4658],{},[705,4627,4628,4631,4634,4637],{},[722,4629,4630],{},"STRING_AGG (10M rows)",[722,4632,4633],{},"45s",[722,4635,4636],{},"8s",[722,4638,4639],{},[432,4640,4641],{},"5.6x",[705,4643,4644,4647,4650,4653],{},[722,4645,4646],{},"Window functions (10M rows)",[722,4648,4649],{},"120s",[722,4651,4652],{},"18s",[722,4654,4655],{},[432,4656,4657],{},"6.7x",[705,4659,4660,4663,4666,4669],{},[722,4661,4662],{},"PERCENTILE_CONT (50M rows)",[722,4664,4665],{},"380s",[722,4667,4668],{},"42s",[722,4670,4671],{},[432,4672,4673],{},"9x",[970,4675,4677],{"className":972,"code":4676,"language":974,"meta":975,"style":975},"-- Batch mode tự động kích hoạt với compatible level 170 (2025)\nALTER DATABASE MyDB SET COMPATIBILITY_LEVEL = 170;\n\n-- Kiểm tra execution plan: tìm operator \"Batch Hash Aggregate\"\n-- hoặc \"Batch Window Aggregate\" thay vì row-mode tương ứng\n\n-- Ép buộc row mode (để compare)\nSELECT Category, STRING_AGG(Name, ', ')\nFROM Products\nGROUP BY Category\nOPTION (USE HINT('DISALLOW_BATCH_MODE'));\n",[484,4678,4679,4684,4689,4693,4698,4703,4707,4712,4717,4721,4726],{"__ignoreMap":975},[979,4680,4681],{"class":981,"line":982},[979,4682,4683],{},"-- Batch mode tự động kích hoạt với compatible level 170 (2025)\n",[979,4685,4686],{"class":981,"line":988},[979,4687,4688],{},"ALTER DATABASE MyDB SET COMPATIBILITY_LEVEL = 170;\n",[979,4690,4691],{"class":981,"line":1156},[979,4692,1771],{"emptyLinePlaceholder":1770},[979,4694,4695],{"class":981,"line":1162},[979,4696,4697],{},"-- Kiểm tra execution plan: tìm operator \"Batch Hash Aggregate\"\n",[979,4699,4700],{"class":981,"line":1197},[979,4701,4702],{},"-- hoặc \"Batch Window Aggregate\" thay vì row-mode tương ứng\n",[979,4704,4705],{"class":981,"line":1761},[979,4706,1771],{"emptyLinePlaceholder":1770},[979,4708,4709],{"class":981,"line":1767},[979,4710,4711],{},"-- Ép buộc row mode (để compare)\n",[979,4713,4714],{"class":981,"line":1774},[979,4715,4716],{},"SELECT Category, STRING_AGG(Name, ', ')\n",[979,4718,4719],{"class":981,"line":1780},[979,4720,3075],{},[979,4722,4723],{"class":981,"line":1786},[979,4724,4725],{},"GROUP BY Category\n",[979,4727,4728],{"class":981,"line":1792},[979,4729,4730],{},"OPTION (USE HINT('DISALLOW_BATCH_MODE'));\n",[427,4732,4733],{"color":467,"icon":468},"Batch Mode trên Rowstore là game-changer cho ETL\u002Fanalytics query — không cần Columnstore index, không cần thay đổi schema. Chỉ cần nâng compatibility level lên 170. Query có window function hoặc STRING_AGG chạy trên bảng > 1M row sẽ thấy khác biệt rõ nhất.",[437,4735,4737],{"id":4736},"n-sql-server-2025-edition-cloud-hybrid","N. SQL Server 2025 — Edition, Cloud & Hybrid",[442,4739,4741],{"id":4740},"_79-express-edition-2025-có-gì-mới","79. Express Edition 2025 có gì mới?",[447,4743,4744,4745,4748],{},"SQL Server 2025 Express Edition có thay đổi ",[432,4746,4747],{},"lớn nhất trong lịch sử Express",":",[699,4750,4751,4764],{},[702,4752,4753],{},[705,4754,4755,4758,4761],{},[708,4756,4757],{},"Tính năng",[708,4759,4760],{},"Express 2019\u002F2022",[708,4762,4763],{},"Express 2025",[717,4765,4766,4781,4792,4802,4812,4821,4829,4838],{},[705,4767,4768,4771,4776],{},[722,4769,4770],{},"Max database size",[722,4772,4773],{},[432,4774,4775],{},"10 GB",[722,4777,4778],{},[432,4779,4780],{},"50 GB",[705,4782,4783,4786,4789],{},[722,4784,4785],{},"RAM sử dụng",[722,4787,4788],{},"~1.4 GB",[722,4790,4791],{},"~2 GB (buffer pool)",[705,4793,4794,4797,4800],{},[722,4795,4796],{},"CPU",[722,4798,4799],{},"1 socket \u002F 4 cores",[722,4801,4799],{},[705,4803,4804,4807,4810],{},[722,4805,4806],{},"VECTOR type",[722,4808,4809],{},"Không có",[722,4811,900],{},[705,4813,4814,4817,4819],{},[722,4815,4816],{},"Native JSON",[722,4818,4809],{},[722,4820,900],{},[705,4822,4823,4825,4827],{},[722,4824,1649],{},[722,4826,4809],{},[722,4828,900],{},[705,4830,4831,4833,4835],{},[722,4832,1631],{},[722,4834,4809],{},[722,4836,4837],{},"Có (giới hạn)",[705,4839,4840,4842,4844],{},[722,4841,1691],{},[722,4843,726],{},[722,4845,900],{},[970,4847,4851],{"className":4848,"code":4849,"language":4850,"meta":975,"style":975},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Pull và chạy SQL Server 2025 Express trên Docker\ndocker run -e \"ACCEPT_EULA=Y\" -e \"MSSQL_EDITION=Express\" \\\n  -p 1433:1433 \\\n  mcr.microsoft.com\u002Fmssql\u002Fserver:2025-latest\n","bash",[484,4852,4853,4859,4895,4905],{"__ignoreMap":975},[979,4854,4855],{"class":981,"line":982},[979,4856,4858],{"class":4857},"sHwdD","# Pull và chạy SQL Server 2025 Express trên Docker\n",[979,4860,4861,4865,4869,4872,4876,4879,4882,4884,4886,4889,4891],{"class":981,"line":988},[979,4862,4864],{"class":4863},"sBMFI","docker",[979,4866,4868],{"class":4867},"sfazB"," run",[979,4870,4871],{"class":4867}," -e",[979,4873,4875],{"class":4874},"sMK4o"," \"",[979,4877,4878],{"class":4867},"ACCEPT_EULA=Y",[979,4880,4881],{"class":4874},"\"",[979,4883,4871],{"class":4867},[979,4885,4875],{"class":4874},[979,4887,4888],{"class":4867},"MSSQL_EDITION=Express",[979,4890,4881],{"class":4874},[979,4892,4894],{"class":4893},"sTEyZ"," \\\n",[979,4896,4897,4900,4903],{"class":981,"line":1156},[979,4898,4899],{"class":4867},"  -p",[979,4901,4902],{"class":4867}," 1433:1433",[979,4904,4894],{"class":4893},[979,4906,4907],{"class":981,"line":1162},[979,4908,4909],{"class":4867},"  mcr.microsoft.com\u002Fmssql\u002Fserver:2025-latest\n",[427,4911,4912],{"color":467,"icon":468},"50GB thay đổi hoàn toàn game: Express giờ có thể chạy production cho phần lớn SME app, blog, e-commerce nhỏ, internal tool. Kết hợp với AI feature (VECTOR, JSON native), Express 2025 là lựa chọn cực mạnh để build proof-of-concept RAG\u002FAI app mà không tốn license.",[442,4914,4916],{"id":4915},"_80-sql-server-on-linux-2025-khác-windows-ở-đâu","80. SQL Server on Linux 2025 khác Windows ở đâu?",[447,4918,4919,4920,4923],{},"SQL Server 2025 on Linux đạt ",[432,4921,4922],{},"near-complete feature parity"," với Windows:",[699,4925,4926,4939],{},[702,4927,4928],{},[705,4929,4930,4933,4936],{},[708,4931,4932],{},"Feature",[708,4934,4935],{},"Windows 2025",[708,4937,4938],{},"Linux 2025",[717,4940,4941,4950,4960,4969,4979,4987,4996,5005,5014,5025],{},[705,4942,4943,4946,4948],{},[722,4944,4945],{},"Engine (VECTOR, JSON, RegEx, DiskANN)",[722,4947,900],{},[722,4949,900],{},[705,4951,4952,4955,4957],{},[722,4953,4954],{},"Always On Availability Groups",[722,4956,900],{},[722,4958,4959],{},"✅ (Pacemaker)",[705,4961,4962,4965,4967],{},[722,4963,4964],{},"Machine Learning Services",[722,4966,900],{},[722,4968,900],{},[705,4970,4971,4974,4976],{},[722,4972,4973],{},"Active Directory Auth",[722,4975,900],{},[722,4977,4978],{},"✅ (Kerberos)",[705,4980,4981,4983,4985],{},[722,4982,1637],{},[722,4984,900],{},[722,4986,900],{},[705,4988,4989,4992,4994],{},[722,4990,4991],{},"SSIS \u002F SSRS \u002F SSAS",[722,4993,900],{},[722,4995,903],{},[705,4997,4998,5001,5003],{},[722,4999,5000],{},"FileTable \u002F FileStream",[722,5002,900],{},[722,5004,903],{},[705,5006,5007,5010,5012],{},[722,5008,5009],{},"Stretch Database",[722,5011,900],{},[722,5013,903],{},[705,5015,5016,5019,5022],{},[722,5017,5018],{},"Kubernetes Operator",[722,5020,5021],{},"Không cần",[722,5023,5024],{},"✅ (native)",[705,5026,5027,5030,5033],{},[722,5028,5029],{},"Container \u002F Podman",[722,5031,5032],{},"OK",[722,5034,5035],{},"✅ Tối ưu",[447,5037,5038],{},[432,5039,5040],{},"Linux-specific advantages:",[970,5042,5044],{"className":4848,"code":5043,"language":4850,"meta":975,"style":975},"# Triển khai trên K8s với SQL Server Operator 2025\nkubectl apply -f sqlserver-2025-operator.yaml\n\n# Tự động failover, backup, scale\nkubectl get sqlservers\n",[484,5045,5046,5051,5065,5069,5074],{"__ignoreMap":975},[979,5047,5048],{"class":981,"line":982},[979,5049,5050],{"class":4857},"# Triển khai trên K8s với SQL Server Operator 2025\n",[979,5052,5053,5056,5059,5062],{"class":981,"line":988},[979,5054,5055],{"class":4863},"kubectl",[979,5057,5058],{"class":4867}," apply",[979,5060,5061],{"class":4867}," -f",[979,5063,5064],{"class":4867}," sqlserver-2025-operator.yaml\n",[979,5066,5067],{"class":981,"line":1156},[979,5068,1771],{"emptyLinePlaceholder":1770},[979,5070,5071],{"class":981,"line":1162},[979,5072,5073],{"class":4857},"# Tự động failover, backup, scale\n",[979,5075,5076,5078,5081],{"class":981,"line":1197},[979,5077,5055],{"class":4863},[979,5079,5080],{"class":4867}," get",[979,5082,5083],{"class":4867}," sqlservers\n",[427,5085,5086],{"color":467,"icon":468},"Nếu stack của bạn là: .NET backend + SQL Server + Docker\u002FK8s → deploy toàn bộ lên Linux. Feature không có (SSIS, SSRS) thường đã được thay thế bởi Azure Data Factory + Power BI cloud. Linux container image SQL 2025 nhẹ hơn Windows image ~40%.",[442,5088,5090],{"id":5089},"_81-azure-arc-cho-sql-server-2025-mang-lại-lợi-ích-gì","81. Azure Arc cho SQL Server 2025 mang lại lợi ích gì?",[447,5092,5093,5095],{},[432,5094,1709],{}," là bridge giữa on-premise SQL Server và Azure cloud — quản lý SQL Server anywhere (on-prem, edge, other cloud) từ Azure portal:",[970,5097,5099],{"className":972,"code":5098,"language":974,"meta":975,"style":975},"-- Connect SQL Server 2025 vào Azure Arc\n-- (chạy trên máy on-premise)\nEXEC sys.arc_connect\n    @tenant_id = 'your-tenant-id',\n    @subscription_id = 'your-subscription-id',\n    @resource_group = 'sql-servers-rg';\n",[484,5100,5101,5106,5111,5116,5121,5126],{"__ignoreMap":975},[979,5102,5103],{"class":981,"line":982},[979,5104,5105],{},"-- Connect SQL Server 2025 vào Azure Arc\n",[979,5107,5108],{"class":981,"line":988},[979,5109,5110],{},"-- (chạy trên máy on-premise)\n",[979,5112,5113],{"class":981,"line":1156},[979,5114,5115],{},"EXEC sys.arc_connect\n",[979,5117,5118],{"class":981,"line":1162},[979,5119,5120],{},"    @tenant_id = 'your-tenant-id',\n",[979,5122,5123],{"class":981,"line":1197},[979,5124,5125],{},"    @subscription_id = 'your-subscription-id',\n",[979,5127,5128],{"class":981,"line":1761},[979,5129,5130],{},"    @resource_group = 'sql-servers-rg';\n",[447,5132,5133],{},[432,5134,5135],{},"Lợi ích chính:",[699,5137,5138,5147],{},[702,5139,5140],{},[705,5141,5142,5144],{},[708,5143,4757],{},[708,5145,5146],{},"Mô tả",[717,5148,5149,5159,5169,5179,5189,5199,5209],{},[705,5150,5151,5156],{},[722,5152,5153],{},[432,5154,5155],{},"Azure Update Manager",[722,5157,5158],{},"Patch SQL Server tự động, lên lịch, theo policy",[705,5160,5161,5166],{},[722,5162,5163],{},[432,5164,5165],{},"Microsoft Defender for SQL",[722,5167,5168],{},"Phát hiện SQL injection, anomaly, vulnerability assessment",[705,5170,5171,5176],{},[722,5172,5173],{},[432,5174,5175],{},"Microsoft Purview",[722,5177,5178],{},"Data catalog, classification, lineage — scan on-prem data",[705,5180,5181,5186],{},[722,5182,5183],{},[432,5184,5185],{},"Best Practice Assessment",[722,5187,5188],{},"Check config SQL Server theo best practice Microsoft",[705,5190,5191,5196],{},[722,5192,5193],{},[432,5194,5195],{},"Centralized Monitoring",[722,5197,5198],{},"Tất cả SQL instance (on-prem + cloud) trong 1 dashboard",[705,5200,5201,5206],{},[722,5202,5203],{},[432,5204,5205],{},"Billing flexibility",[722,5207,5208],{},"Pay-as-you-go license qua Azure, không cần SA contract",[705,5210,5211,5216],{},[722,5212,5213],{},[432,5214,5215],{},"Failover to Azure",[722,5217,5218],{},"DR site là Azure SQL Managed Instance — Arc tự động failover",[447,5220,5221],{},"::callout{icon=\"i-lucide-star\" color=\"warning\">\nAzure Arc đặc biệt hữu ích cho doanh nghiệp có SQL Server on-prem + hybrid. Thay vì quản lý từng server riêng lẻ, toàn bộ fleet được manage từ Azure portal: patch, security audit, compliance — tất cả tập trung. Free cho management, pay cho advanced security feature.\n::",[437,5223,5225],{"id":5224},"p-sql-on-linux-azure-hybrid-fabric","P. SQL on Linux, Azure Hybrid & Fabric",[442,5227,5229],{"id":5228},"_86-sql-server-on-linux-khác-windows-ở-điểm-nào","86. SQL Server on Linux khác Windows ở điểm nào?",[699,5231,5232,5244],{},[702,5233,5234],{},[705,5235,5236,5238,5241],{},[708,5237,1878],{},[708,5239,5240],{},"Windows",[708,5242,5243],{},"Linux",[717,5245,5246,5259,5275,5288,5305,5321,5334,5346,5359],{},[705,5247,5248,5253,5256],{},[722,5249,5250],{},[432,5251,5252],{},"Process model",[722,5254,5255],{},"SQL Server service chạy trong Windows kernel",[722,5257,5258],{},"Chạy như process Linux thông thường",[705,5260,5261,5266,5269],{},[722,5262,5263],{},[432,5264,5265],{},"Authentication",[722,5267,5268],{},"Windows Auth + SQL Auth",[722,5270,5271,5274],{},[432,5272,5273],{},"Chỉ SQL Auth"," (không có AD native — dùng Kerberos\u002FPAM hoặc Azure Arc để bắc cầu)",[705,5276,5277,5282,5285],{},[722,5278,5279],{},[432,5280,5281],{},"File system",[722,5283,5284],{},"NTFS, ReFS",[722,5286,5287],{},"EXT4, XFS",[705,5289,5290,5295,5298],{},[722,5291,5292],{},[432,5293,5294],{},"TempDB",[722,5296,5297],{},"File trên disk",[722,5299,5300,5301,5304],{},"Có thể dùng ",[432,5302,5303],{},"tmpfs"," (RAM disk) — nhanh hơn nhiều",[705,5306,5307,5312,5315],{},[722,5308,5309],{},[432,5310,5311],{},"SQL Server Agent",[722,5313,5314],{},"Service riêng, bật mặc định",[722,5316,5317,5318],{},"Tắt mặc định, bật bằng ",[484,5319,5320],{},"mssql-conf",[705,5322,5323,5328,5331],{},[722,5324,5325],{},[432,5326,5327],{},"High Availability",[722,5329,5330],{},"Always On AG, FCI với WSFC",[722,5332,5333],{},"AG với Pacemaker (RHEL\u002FUbuntu), không có FCI",[705,5335,5336,5340,5343],{},[722,5337,5338],{},[432,5339,2557],{},[722,5341,5342],{},"Tối ưu Windows kernel",[722,5344,5345],{},"Gần tương đương (2022+: \u003C 5% khác biệt)",[705,5347,5348,5353,5356],{},[722,5349,5350],{},[432,5351,5352],{},"Container",[722,5354,5355],{},"Docker Windows container (lớn, ít dùng)",[722,5357,5358],{},"Docker Linux container (40% nhỏ hơn, nhanh hơn)",[705,5360,5361,5366,5369],{},[722,5362,5363],{},[432,5364,5365],{},"SSIS\u002FSSAS\u002FSSRS",[722,5367,5368],{},"Có đầy đủ",[722,5370,5371,5374],{},[432,5372,5373],{},"Không hỗ trợ"," (chỉ có Database Engine)",[427,5376,5377,5378,5381],{"color":467,"icon":468},"⭐ ",[432,5379,5380],{},"Container Linux là default recommendation 2026:"," image nhẹ hơn (1.5GB vs 6GB), start nhanh hơn, dễ CI\u002FCD. Production on-prem vẫn ưu tiên Windows nếu cần full stack (SSIS\u002FSSAS\u002FSSRS). Cloud thì Azure SQL hoặc Azure VM với SQL Linux đều OK.",[442,5383,5385],{"id":5384},"_87-azure-arc-enabled-sql-server-là-gì-lợi-ích","87. Azure Arc-enabled SQL Server là gì? Lợi ích?",[447,5387,5388],{},"Azure Arc = bridge kết nối SQL Server on-prem (hoặc cloud khác) vào Azure control plane:",[970,5390,5393],{"className":5391,"code":5392,"language":2209},[2207],"┌─────────────────────────────────────────────────┐\n│                  Azure Portal                     │\n│  ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │\n│  │ Security │ │  Update  │ │ Compliance        │ │\n│  │ Center   │ │ Manager  │ │ (Microsoft Purview)│ │\n│  └────┬─────┘ └────┬─────┘ └────────┬─────────┘ │\n└───────┼────────────┼───────────────┼────────────┘\n        │            │               │\n   ┌────▼────────────▼───────────────▼────────────┐\n   │         Azure Arc agent (on-prem)             │\n   │  ┌──────────┐  ┌─────────────┐               │\n   │  │ SQL Svr 1│  │ SQL Svr 2   │  ...          │\n   │  │ (Windows)│  │ (Linux)     │               │\n   │  └──────────┘  └─────────────┘               │\n   └──────────────────────────────────────────────┘\n",[484,5394,5392],{"__ignoreMap":975},[447,5396,5397],{},[432,5398,5399],{},"Lợi ích cụ thể:",[699,5401,5402,5411],{},[702,5403,5404],{},[705,5405,5406,5408],{},[708,5407,4757],{},[708,5409,5410],{},"Chi tiết",[717,5412,5413,5423,5433,5443,5453,5463],{},[705,5414,5415,5420],{},[722,5416,5417],{},[432,5418,5419],{},"Unified management",[722,5421,5422],{},"Quản lý toàn bộ fleet SQL Server (on-prem + cloud) từ 1 Azure portal",[705,5424,5425,5430],{},[722,5426,5427],{},[432,5428,5429],{},"Microsoft Entra ID auth",[722,5431,5432],{},"Dùng Entra ID (Azure AD cũ) để đăng nhập SQL Server on-prem — không cần Windows AD",[705,5434,5435,5440],{},[722,5436,5437],{},[432,5438,5439],{},"Automated updates",[722,5441,5442],{},"Patch SQL Server tự động theo schedule, giống Windows Update",[705,5444,5445,5450],{},[722,5446,5447],{},[432,5448,5449],{},"Security compliance",[722,5451,5452],{},"Microsoft Purview đánh giá security posture, phát hiện misconfiguration",[705,5454,5455,5460],{},[722,5456,5457],{},[432,5458,5459],{},"Best practices assessment",[722,5461,5462],{},"Tự động scan instance, so sánh với best practice, report gap",[705,5464,5465,5470],{},[722,5466,5467],{},[432,5468,5469],{},"Cost management",[722,5471,5472,5473,5476],{},"Nếu có Software Assurance, Azure Arc SQL được ",[432,5474,5475],{},"giảm đến 20%"," Azure cost khi migrate lên cloud sau này",[427,5478,5377,5479,5482],{"color":429,"icon":468},[432,5480,5481],{},"Khi nào đầu tư Azure Arc?"," Doanh nghiệp có > 10 SQL Server instance on-prem, muốn centralized management + security compliance. Đặc biệt hữu ích khi hybrid strategy: 1 phần workload đã migrate Azure, phần còn lại vẫn on-prem.",[442,5484,5486],{"id":5485},"_88-azure-sql-hyperscale-khi-nào-chọn-thay-vì-sql-server-on-prem","88. Azure SQL Hyperscale — khi nào chọn thay vì SQL Server on-prem?",[699,5488,5489,5502],{},[702,5490,5491],{},[705,5492,5493,5496,5499],{},[708,5494,5495],{},"Yếu tố",[708,5497,5498],{},"SQL Server on-prem",[708,5500,5501],{},"Azure SQL Hyperscale",[717,5503,5504,5519,5536,5552,5567,5583,5598,5611],{},[705,5505,5506,5510,5513],{},[722,5507,5508],{},[432,5509,1901],{},[722,5511,5512],{},"Max ~524PB (lý thuyết), thực tế vài TB",[722,5514,5515,5518],{},[432,5516,5517],{},"Lên đến 100TB"," (auto-grow, không cần filegroup planning)",[705,5520,5521,5526,5529],{},[722,5522,5523],{},[432,5524,5525],{},"Scale compute",[722,5527,5528],{},"Scale-up (thêm CPU\u002FRAM) mất downtime",[722,5530,5531,5532,5535],{},"Scale-up\u002Fdown ",[432,5533,5534],{},"online",", vài giây",[705,5537,5538,5543,5546],{},[722,5539,5540],{},[432,5541,5542],{},"Scale reads",[722,5544,5545],{},"AG secondary, max 8 replica",[722,5547,5548,5551],{},[432,5549,5550],{},"0-30 named replicas",", tạo trong \u003C 1 phút",[705,5553,5554,5559,5562],{},[722,5555,5556],{},[432,5557,5558],{},"Failover",[722,5560,5561],{},"30s-2 phút (AG failover)",[722,5563,5564],{},[432,5565,5566],{},"\u003C 10 giây",[705,5568,5569,5574,5577],{},[722,5570,5571],{},[432,5572,5573],{},"Backup\u002FRestore",[722,5575,5576],{},"Thủ công (maintenance plan, agent job)",[722,5578,5579,5582],{},[432,5580,5581],{},"Snapshot backup \u003C 10 phút"," cho DB bất kỳ kích thước (kể cả 100TB)",[705,5584,5585,5590,5593],{},[722,5586,5587],{},[432,5588,5589],{},"RCSI \u002F Snapshot",[722,5591,5592],{},"Phải bật thủ công",[722,5594,5595],{},[432,5596,5597],{},"Bật mặc định",[705,5599,5600,5605,5608],{},[722,5601,5602],{},[432,5603,5604],{},"Licensing",[722,5606,5607],{},"License + SA hoặc pay-as-you-go",[722,5609,5610],{},"Pay-as-you-go hoặc reserved instance (tiết kiệm ~35%)",[705,5612,5613,5618,5621],{},[722,5614,5615],{},[432,5616,5617],{},"Enterprise feature",[722,5619,5620],{},"Đầy đủ (AG, partitioning, SSIS...)",[722,5622,5623],{},"Một số feature không có (SSIS, SSAS, Agent job hạn chế một số thứ)",[427,5625,5626,5629],{"color":467,"icon":268},[432,5627,5628],{},"Hyperscale snapshot restore",": restore database 100TB trong \u003C 10 phút — là killer feature. SQL Server on-prem restore 10TB có thể mất 10+ giờ. Cơ chế: page server dùng storage snapshot thay vì copy data.",[442,5631,5633],{"id":5632},"_89-sql-database-trong-microsoft-fabric-dùng-khi-nào","89. SQL Database trong Microsoft Fabric — dùng khi nào?",[970,5635,5637],{"className":972,"code":5636,"language":974,"meta":975,"style":975},"-- Không cần CREATE SERVER, chỉ cần CREATE DATABASE\nCREATE DATABASE SalesAnalytics;\nGO\n\nUSE SalesAnalytics;\nCREATE TABLE orders (...);\n-- Dùng T-SQL y hệt, có VECTOR, JSON, RegEx đầy đủ\n",[484,5638,5639,5644,5649,5654,5658,5663,5668],{"__ignoreMap":975},[979,5640,5641],{"class":981,"line":982},[979,5642,5643],{},"-- Không cần CREATE SERVER, chỉ cần CREATE DATABASE\n",[979,5645,5646],{"class":981,"line":988},[979,5647,5648],{},"CREATE DATABASE SalesAnalytics;\n",[979,5650,5651],{"class":981,"line":1156},[979,5652,5653],{},"GO\n",[979,5655,5656],{"class":981,"line":1162},[979,5657,1771],{"emptyLinePlaceholder":1770},[979,5659,5660],{"class":981,"line":1197},[979,5661,5662],{},"USE SalesAnalytics;\n",[979,5664,5665],{"class":981,"line":1761},[979,5666,5667],{},"CREATE TABLE orders (...);\n",[979,5669,5670],{"class":981,"line":1767},[979,5671,5672],{},"-- Dùng T-SQL y hệt, có VECTOR, JSON, RegEx đầy đủ\n",[447,5674,5675],{},[432,5676,5677],{},"Khác biệt chính với Azure SQL Database truyền thống:",[699,5679,5680,5692],{},[702,5681,5682],{},[705,5683,5684,5686,5689],{},[708,5685],{},[708,5687,5688],{},"Azure SQL Database",[708,5690,5691],{},"Fabric SQL Database",[717,5693,5694,5713,5730,5746,5762,5775],{},[705,5695,5696,5701,5704],{},[722,5697,5698],{},[432,5699,5700],{},"Provision",[722,5702,5703],{},"Cần tạo logical server → tạo DB",[722,5705,5706,5709,5710],{},[484,5707,5708],{},"CREATE DATABASE"," — ",[432,5711,5712],{},"serverless hoàn toàn",[705,5714,5715,5720,5723],{},[722,5716,5717],{},[432,5718,5719],{},"Billing",[722,5721,5722],{},"Theo vCore\u002FDTU + storage",[722,5724,5725,5726,5729],{},"Theo ",[432,5727,5728],{},"dung lượng data + compute dùng thực tế"," trong Fabric capacity",[705,5731,5732,5737,5740],{},[722,5733,5734],{},[432,5735,5736],{},"Copilot",[722,5738,5739],{},"Qua SSMS 22",[722,5741,5742,5745],{},[432,5743,5744],{},"Tích hợp sẵn"," trong Fabric portal (NL → SQL, tự động suggest)",[705,5747,5748,5753,5756],{},[722,5749,5750],{},[432,5751,5752],{},"Ecosystem",[722,5754,5755],{},"Độc lập, connect từ app ngoài",[722,5757,5758,5761],{},[432,5759,5760],{},"Tích hợp OneLake",", Power BI direct query, notebook, data pipeline",[705,5763,5764,5769,5772],{},[722,5765,5766],{},[432,5767,5768],{},"Scale giới hạn",[722,5770,5771],{},"Hyperscale 100TB",[722,5773,5774],{},"Fabric capacity giới hạn (tuỳ SKU)",[705,5776,5777,5781,5784],{},[722,5778,5779],{},[432,5780,2568],{},[722,5782,5783],{},"Production OLTP app",[722,5785,5786],{},"Analytics, reporting, data warehouse nhỏ, team muốn SQL mà không muốn DevOps",[427,5788,5377,5789,5792],{"color":429,"icon":468},[432,5790,5791],{},"Fabric SQL không thay thế Azure SQL Database."," Fabric SQL = SQL cho analytics team (dữ liệu đã ở Fabric). Azure SQL Database = SQL cho production application (OLTP, REST API, high concurrency).",[442,5794,5796],{"id":5795},"_90-làm-sao-kết-nối-sql-server-on-prem-với-azure-services-mà-không-expose-ra-internet","90. Làm sao kết nối SQL Server on-prem với Azure services mà không expose ra internet?",[970,5798,5800],{"className":4848,"code":5799,"language":4850,"meta":975,"style":975},"# Azure Arc: cài agent lên SQL Server on-prem\n# Agent chỉ cần OUTBOUND HTTPS (443) → không cần mở inbound port\n\n# 1. Tạo Azure Arc resource trong portal\naz connectedmachine create --resource-group my-rg \\\n    --name sql-onprem-01 --location westeurope\n\n# 2. Cài Azure Connected Machine agent lên server on-prem\n# (download script từ Azure portal)\n\n# 3. Enable SQL Server extension\naz connectedmachine extension create \\\n    --machine-name sql-onprem-01 \\\n    --name WindowsAgent.SqlServer \\\n    --type WindowsAgent.SqlServer\n\n# 4. SQL Server xuất hiện trong Azure portal → quản lý như cloud resource\n# Dùng Entra ID để auth: không cần Windows AD!\n",[484,5801,5802,5807,5812,5816,5821,5840,5854,5858,5863,5868,5872,5877,5890,5899,5908,5916,5920,5925],{"__ignoreMap":975},[979,5803,5804],{"class":981,"line":982},[979,5805,5806],{"class":4857},"# Azure Arc: cài agent lên SQL Server on-prem\n",[979,5808,5809],{"class":981,"line":988},[979,5810,5811],{"class":4857},"# Agent chỉ cần OUTBOUND HTTPS (443) → không cần mở inbound port\n",[979,5813,5814],{"class":981,"line":1156},[979,5815,1771],{"emptyLinePlaceholder":1770},[979,5817,5818],{"class":981,"line":1162},[979,5819,5820],{"class":4857},"# 1. Tạo Azure Arc resource trong portal\n",[979,5822,5823,5826,5829,5832,5835,5838],{"class":981,"line":1197},[979,5824,5825],{"class":4863},"az",[979,5827,5828],{"class":4867}," connectedmachine",[979,5830,5831],{"class":4867}," create",[979,5833,5834],{"class":4867}," --resource-group",[979,5836,5837],{"class":4867}," my-rg",[979,5839,4894],{"class":4893},[979,5841,5842,5845,5848,5851],{"class":981,"line":1761},[979,5843,5844],{"class":4867},"    --name",[979,5846,5847],{"class":4867}," sql-onprem-01",[979,5849,5850],{"class":4867}," --location",[979,5852,5853],{"class":4867}," westeurope\n",[979,5855,5856],{"class":981,"line":1767},[979,5857,1771],{"emptyLinePlaceholder":1770},[979,5859,5860],{"class":981,"line":1774},[979,5861,5862],{"class":4857},"# 2. Cài Azure Connected Machine agent lên server on-prem\n",[979,5864,5865],{"class":981,"line":1780},[979,5866,5867],{"class":4857},"# (download script từ Azure portal)\n",[979,5869,5870],{"class":981,"line":1786},[979,5871,1771],{"emptyLinePlaceholder":1770},[979,5873,5874],{"class":981,"line":1792},[979,5875,5876],{"class":4857},"# 3. Enable SQL Server extension\n",[979,5878,5879,5881,5883,5886,5888],{"class":981,"line":1798},[979,5880,5825],{"class":4863},[979,5882,5828],{"class":4867},[979,5884,5885],{"class":4867}," extension",[979,5887,5831],{"class":4867},[979,5889,4894],{"class":4893},[979,5891,5892,5895,5897],{"class":981,"line":1804},[979,5893,5894],{"class":4867},"    --machine-name",[979,5896,5847],{"class":4867},[979,5898,4894],{"class":4893},[979,5900,5901,5903,5906],{"class":981,"line":1810},[979,5902,5844],{"class":4867},[979,5904,5905],{"class":4867}," WindowsAgent.SqlServer",[979,5907,4894],{"class":4893},[979,5909,5910,5913],{"class":981,"line":2124},[979,5911,5912],{"class":4867},"    --type",[979,5914,5915],{"class":4867}," WindowsAgent.SqlServer\n",[979,5917,5918],{"class":981,"line":2129},[979,5919,1771],{"emptyLinePlaceholder":1770},[979,5921,5922],{"class":981,"line":2135},[979,5923,5924],{"class":4857},"# 4. SQL Server xuất hiện trong Azure portal → quản lý như cloud resource\n",[979,5926,5927],{"class":981,"line":2141},[979,5928,5929],{"class":4857},"# Dùng Entra ID để auth: không cần Windows AD!\n",[427,5931,5933,5936,5937,5940,5941,5944],{"color":467,"icon":5932},"i-lucide-alert-triangle",[432,5934,5935],{},"Security note:"," Azure Arc agent dùng ",[432,5938,5939],{},"outbound-only"," connection (HTTPS 443) → không cần mở firewall inbound. Phù hợp với chính sách bảo mật doanh nghiệp. Data (query result, row data) ",[432,5942,5943],{},"không gửi lên Azure"," — chỉ metadata (instance name, version, config, health status).",[437,5946,5948],{"id":5947},"o-câu-trick-scenario","O. Câu trick & scenario",[442,5950,5952,5953,5956],{"id":5951},"_82-cho-1-bảng-100m-row-query-where-status-active-chậm-tìm-nguyên-nhân","82. Cho 1 bảng 100M row, query ",[484,5954,5955],{},"WHERE Status = 'Active'"," chậm. Tìm nguyên nhân?",[447,5958,5959],{},"Bước:",[1571,5961,5962,5969,5972,5982],{},[543,5963,5964,5965,5968],{},"Check có index trên ",[484,5966,5967],{},"Status"," không.",[543,5970,5971],{},"Check selectivity: nếu 80% row là Active → index vô dụng, phải scan.",[543,5973,5974,5975,5978,5979,5981],{},"Tạo ",[432,5976,5977],{},"filtered index"," ",[484,5980,5955],{}," nếu cần.",[543,5983,5984],{},"Hoặc partition theo Status.",[442,5986,5988,5989,5992,5993,5996],{"id":5987},"_83-migration-đổi-cột-int-bigint-trên-bảng-1-tỷ-row-không-downtime","83. Migration đổi cột ",[484,5990,5991],{},"INT"," → ",[484,5994,5995],{},"BIGINT"," trên bảng 1 tỷ row, không downtime?",[540,5998,5999,6006,6009,6012,6015],{},[543,6000,6001,6002,6005],{},"Tạo cột mới ",[484,6003,6004],{},"BIGINT NULL",", default NULL.",[543,6007,6008],{},"Backfill batch theo PK range (1000 row\u002Fbatch), tránh long lock.",[543,6010,6011],{},"Sau khi backfill xong: trigger duplicate ghi trong transition.",[543,6013,6014],{},"Đổi index, FK trỏ sang cột mới.",[543,6016,6017],{},"Drop cột cũ.",[442,6019,6021],{"id":6020},"_84-server-slow-ram-đầy-cpu-cao-bạn-check-gì-đầu-tiên","84. Server slow, RAM đầy, CPU cao — bạn check gì đầu tiên?",[540,6023,6024,6030,6036,6042],{},[543,6025,6026,6029],{},[484,6027,6028],{},"sys.dm_exec_query_stats"," — top query theo CPU\u002FIO.",[543,6031,6032,6035],{},[484,6033,6034],{},"sys.dm_os_wait_stats"," — wait type chính (PAGEIOLATCH = thiếu RAM, CXPACKET = parallelism).",[543,6037,6038,6041],{},[484,6039,6040],{},"sys.dm_db_index_usage_stats"," — index dùng nhiều ít.",[543,6043,6044],{},"Check Query Store nếu đã bật.",[442,6046,6048],{"id":6047},"_85-block-với-deadlock-khác-gì","85. Block với Deadlock khác gì?",[540,6050,6051,6057],{},[543,6052,6053,6056],{},[432,6054,6055],{},"Block",": 1 transaction đợi lock từ transaction khác — sẽ tiếp tục khi giải phóng.",[543,6058,6059,6062],{},[432,6060,6061],{},"Deadlock",": 2 transaction đợi lock của nhau vô tận → engine kill 1.",[427,6064,6066,6067],{"color":429,"icon":6065},"i-lucide-arrow-right","Tiếp theo: ",[6068,6069,6070],"a",{"href":204},"PostgreSQL — Giới thiệu & cài đặt",[6072,6073,6074],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":975,"searchDepth":988,"depth":988,"links":6076},[6077,6084,6091,6100,6106,6121,6134,6143,6149,6157,6166,6172,6177,6183,6188,6195],{"id":439,"depth":988,"text":440,"children":6078},[6079,6080,6081,6082,6083],{"id":444,"depth":1156,"text":445},{"id":475,"depth":1156,"text":476},{"id":490,"depth":1156,"text":491},{"id":522,"depth":1156,"text":523},{"id":537,"depth":1156,"text":538},{"id":563,"depth":988,"text":564,"children":6085},[6086,6087,6088,6089,6090],{"id":567,"depth":1156,"text":568},{"id":592,"depth":1156,"text":593},{"id":619,"depth":1156,"text":620},{"id":643,"depth":1156,"text":644},{"id":658,"depth":1156,"text":659},{"id":692,"depth":988,"text":693,"children":6092},[6093,6094,6095,6096,6097,6098,6099],{"id":696,"depth":1156,"text":697},{"id":754,"depth":1156,"text":755},{"id":765,"depth":1156,"text":766},{"id":789,"depth":1156,"text":790},{"id":800,"depth":1156,"text":801},{"id":810,"depth":1156,"text":811},{"id":825,"depth":1156,"text":826},{"id":855,"depth":988,"text":856,"children":6101},[6102,6103,6104,6105],{"id":859,"depth":1156,"text":860},{"id":967,"depth":1156,"text":968},{"id":994,"depth":1156,"text":995},{"id":1004,"depth":1156,"text":1005},{"id":1026,"depth":988,"text":1027,"children":6107},[6108,6109,6110,6111,6112,6113,6114,6115,6116,6117,6118,6119,6120],{"id":1030,"depth":1156,"text":1031},{"id":1045,"depth":1156,"text":1046},{"id":1061,"depth":1156,"text":1062},{"id":1084,"depth":1156,"text":1085},{"id":1094,"depth":1156,"text":1095},{"id":1101,"depth":1156,"text":1102},{"id":1119,"depth":1156,"text":1120},{"id":1137,"depth":1156,"text":1138},{"id":1168,"depth":1156,"text":1169},{"id":1203,"depth":1156,"text":1204},{"id":1214,"depth":1156,"text":1215},{"id":1223,"depth":1156,"text":1224},{"id":1230,"depth":1156,"text":1231},{"id":1246,"depth":988,"text":1247,"children":6122},[6123,6124,6125,6126,6127,6128,6129,6130,6132,6133],{"id":1250,"depth":1156,"text":1251},{"id":1257,"depth":1156,"text":1258},{"id":1269,"depth":1156,"text":1270},{"id":1276,"depth":1156,"text":1277},{"id":1291,"depth":1156,"text":1292},{"id":1307,"depth":1156,"text":1308},{"id":1326,"depth":1156,"text":1327},{"id":1333,"depth":1156,"text":6131},"42. Vì sao WHERE YEAR(date) = 2026 chậm?",{"id":1347,"depth":1156,"text":1348},{"id":1354,"depth":1156,"text":1355},{"id":1382,"depth":988,"text":1383,"children":6135},[6136,6137,6138,6139,6140,6141,6142],{"id":1386,"depth":1156,"text":1387},{"id":1393,"depth":1156,"text":1394},{"id":1403,"depth":1156,"text":1404},{"id":1418,"depth":1156,"text":1419},{"id":1428,"depth":1156,"text":1429},{"id":1438,"depth":1156,"text":1439},{"id":1445,"depth":1156,"text":1446},{"id":1455,"depth":988,"text":1456,"children":6144},[6145,6146,6147,6148],{"id":1459,"depth":1156,"text":1460},{"id":1474,"depth":1156,"text":1475},{"id":1481,"depth":1156,"text":1482},{"id":1502,"depth":1156,"text":1503},{"id":1519,"depth":988,"text":1520,"children":6150},[6151,6153,6154,6155,6156],{"id":1523,"depth":1156,"text":6152},"56. Vì sao tránh SELECT *?",{"id":1534,"depth":1156,"text":1535},{"id":1568,"depth":1156,"text":1569},{"id":1596,"depth":1156,"text":1597},{"id":1603,"depth":1156,"text":1604},{"id":1610,"depth":988,"text":1611,"children":6158},[6159,6160,6161,6162,6163,6164,6165],{"id":1614,"depth":1156,"text":1615},{"id":1716,"depth":1156,"text":1717},{"id":1862,"depth":1156,"text":1863},{"id":1971,"depth":1156,"text":1972},{"id":2191,"depth":1156,"text":2192},{"id":2502,"depth":1156,"text":2503},{"id":2672,"depth":1156,"text":2673},{"id":2803,"depth":988,"text":2804,"children":6167},[6168,6169,6170,6171],{"id":2807,"depth":1156,"text":2808},{"id":2995,"depth":1156,"text":2996},{"id":3149,"depth":1156,"text":3150},{"id":3400,"depth":1156,"text":3401},{"id":3547,"depth":988,"text":3548,"children":6173},[6174,6175,6176],{"id":3551,"depth":1156,"text":3552},{"id":3827,"depth":1156,"text":3828},{"id":3949,"depth":1156,"text":3950},{"id":4127,"depth":988,"text":4128,"children":6178},[6179,6180,6181,6182],{"id":4131,"depth":1156,"text":4132},{"id":4200,"depth":1156,"text":4201},{"id":4361,"depth":1156,"text":4362},{"id":4534,"depth":1156,"text":4535},{"id":4736,"depth":988,"text":4737,"children":6184},[6185,6186,6187],{"id":4740,"depth":1156,"text":4741},{"id":4915,"depth":1156,"text":4916},{"id":5089,"depth":1156,"text":5090},{"id":5224,"depth":988,"text":5225,"children":6189},[6190,6191,6192,6193,6194],{"id":5228,"depth":1156,"text":5229},{"id":5384,"depth":1156,"text":5385},{"id":5485,"depth":1156,"text":5486},{"id":5632,"depth":1156,"text":5633},{"id":5795,"depth":1156,"text":5796},{"id":5947,"depth":988,"text":5948,"children":6196},[6197,6199,6201,6202],{"id":5951,"depth":1156,"text":6198},"82. Cho 1 bảng 100M row, query WHERE Status = 'Active' chậm. Tìm nguyên nhân?",{"id":5987,"depth":1156,"text":6200},"83. Migration đổi cột INT → BIGINT trên bảng 1 tỷ row, không downtime?",{"id":6020,"depth":1156,"text":6021},{"id":6047,"depth":1156,"text":6048},"90+ câu hỏi phỏng vấn SQL Server — đáp án chi tiết, code mẫu, SQL Server 2025 (17.x), Azure SQL Hyperscale, Fabric, Linux.","md",null,{},{"title":193,"icon":196},{"title":422,"description":6203},"Mtw7s4PwngNMY5go0tKlE6_4U3YVeITl-8_5B7G_E-A",[6211,6213],{"title":188,"path":189,"stem":190,"description":6212,"icon":191,"children":-1},"Đặc thù SQL Server 2025 — JSON, Vector Index (DiskANN), Optimized Locking, RegEx, temporal table. Index, execution plan, tuning, query optimization, AI integration, benchmarks.",{"title":173,"path":204,"stem":205,"description":6214,"icon":176,"children":-1},"PostgreSQL 19 (Beta 1 — 04\u002F06\u002F2026) — landmark release với SQL\u002FPGQ graph queries, ON CONFLICT DO SELECT, GROUP BY ALL, temporal data, cùng nền tảng vững chắc từ PG 18.",1783490364760]